简体   繁体   中英

What's the best way of setting up these complicated model associations?

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.

I would recommend something more along the lines of how a forum works for what you're describing:

  • A User has_many videos and comments
  • A video has_many topics
  • A topic belongs_to video and has_many comments
  • Comments belong_to user and topic

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM