Reputation: 2557
Users have many tasks. (tasks.user_id = user_id)
tasks have many tags (implemented through Acts as taggable on
Users have many lists -> which have many tasks (A list is just a wrapper for multiple tags, for example {List id => 1, name => "shopping vacation summer"} will retrieve all tasks tagged with all of those tags)
If, for example, a user goes to the url tags/shopping%20vacation, my code would do a lookup for:
Task.all.tagged_with(["shopping", "vacation"])
There is no Lookup table or foreign key for task.list_id
I want users to be able to share tasks, lists, and tags with other users.
A user sharing a task shares just that task with another user.
A user sharing a list opens up all the tasks in that list to another user.
A user sharing a tag opens all of that users tasks tagged with that tag to another user.
To me, there are a few options, and I'd like some input on the pluses and minuses of each that I may not have thought about.
One is a distinct table for each shareable item:
shared_tasks: task_id, shared_to_id(or user_id) shared_lists: list_id, shared_to_id shared_tags: tag_id, shared_to_id
OR: a polymorphic association with
shareables: shared_id(item_to_share), shared_to_id, shared_type
What are the pluses and minuses of each?
Is there another solution that I haven't thought of?
Upvotes: 1
Views: 480
Reputation: 743
Personally I would change the schema design. Taking Tasks as an example i would now treat it as a many-to-many relationship with User instead of many-to-1 as it is currently. So this would mean removing column tasks.UserId and adding a new table called UserTasks which links Tasks with Users defined as (UserId, TaskId, IsOwner). IsOwner is set to 1 for the user who the task belongs to and 0 if it is shared but belongs to someone else. This will make queries easier for example you could do do a single select to get both owned and shared tasks rather than 2 separate queries and also avoid union's.
Upvotes: 2