Reputation: 13548
I want to add commenting to my application so that an owner of a video can choose for that video the number of commenting columns/forms side-by-side and add a title to each column, and then users can comment on one or more of the columns.
I'm thinking of setting up a VideoComment model whose table looks like this:
-------------------------------------
id | video_id | user_id | comment_id
Then videos would have a has_many through association with comments through VideoComment. Also, users would have a has_many through association with each comments and videos through VideoComment.
To support the multiple columns, I'm thinking of having Comment have a habtm association with another model CommentColumns.
Comment will look like this:
-----------------------------
id | body
CommentColumns will look like this:
------------------------
id | title
And the join table between the comment and commentColumn will be CommentMatching:
------------------------------
comment_id | comment_column_id
My first question is... Am I on the right track, or am I significantly far off?
My second question is... what are all the possible combinations for accessing the different data associations in my controller?
PS. Don't be shy! Please ask me any questions if you would like me to clarify something.
Upvotes: 1
Views: 112
Reputation: 43113
I would recommend something more along the lines of how a forum works for what you're describing:
Then your associations are somewhat simple, you don't really even need any HABTM type associations.
What are all the possible combinations? Loads, but here are a few examples:
#Create a video
@user.videos.create(...attributes...)
#Create a topic
@video.topics.create(...attributes...)
#Create a comment
@topic.comments.create(...attributes...)
#Find all comments from a user
@user.comments
#Find all comments from a particular topics
@topic.comments
#Find all comments from a particular user on a particular topic
@topic.comments.where(:user=>foo)
Hope that makes sense.
-EDIT-
There are different ways you could find all the comments for a particular video, the question is what do you need them for?
If you just want to show them in your view, the simplest thing would be something like this (in HAML):
- for topic in @video.topics do
= topic.title
- for comment in topic.comments do
= comment.body
To return them all as a query I suppose you could do something like...
# untested
Comment.joins(:topics).where('topics.video_id' => video.id)
You could do the same for users comments per video, or you could just add an association where comment belongs_to video. One warning, though... --edited out, see below---
-EDIT-
Ok, I take it back, I remembered my own app wrong. There are no "gotchas" that I can recall about associating comments to both a video and a topic, so the easiest thing would just be to set comments to belong_to videos as well. Be sure and test the associations though so you don't get video = nil
in your records. I didn't test this but as I recall building through the video like @video.topics.first.comments.create(:attributes)
actually doesn't create the video association, only the topic association. I think I had to do something more like:
@topic.comments.create(...attributes..., :video=>@topic.video)
Test that and be sure.
Now that I looked back at my own code what I was remembering trouble with was when I needed to build a nested relationship where an object could belong to a parent of the same class AND a parent container. IE: Comments could have nested replies, so comments belong to topics and also belong to other comments. THAT is what raised trouble. Comments belonging to one topic and one video is fine.
Sorry for the mental lapse :)
After you've got your association just do...
@video.comments.where(:user=>some_user)
..and you'll get all the comments on a video from a particular user.
Upvotes: 4