Welcome to Working With Rails

 

Discussion Forums

Discuss all things Ruby on Rails with perhaps the web's most vibrant group of Ruby on Rails enthusiasts.
Comment Ratings and User tracking
5 Posts
Comment Ratings and User tracking

Say you have a blog with comments, and users are allowed to rate each comment (thumbs up, or thumbs down). What is typically the best way to track which comments users have rated, so you don't allow the user to rate a comment more than once (and you can display that the comment has been already rated by them)?

If it's done via a database table, isn't that going to be loading an ever-increasing list of comments the user has rated each time you load the user?

I think you need to have the many to many table of comment_user

Here's a relatively standard and straightforward way to model this:

Each rating will apply to one comment, and will be made by one user. A user may rate multiple comments, and a comment may be rated by multiple users. So, you have a relatively straightforward many-to-many relationship between users and comments. So, your associations would look something like this:

class User < AR::Base
  has_many :ratings
  has_many :comments, :through => :ratings
end

class Comment < AR::Base
  has_many :ratings
  has{_many :users, :through => :ratings
end

class Rating < AR::Base
  belongs_to :user
  belongs_to :comment

You'll likely want to give your associations more descriptive names (e.g. User#rated_comments, rather than simply User#comments, but I've left it simple to avoid muddying the waters).

With regard to your performance concern, remember that ActiveRecord associations will not load anything from the database until you reference them. Also, they won't bring any rows back from the database that you don't ask for. Thus, if you do this:

@user.ratings

you're asking for all of the ratings associated to that user, and the SQL will look something like

SELECT * FROM ratings WHERE user_id = 1

However, if you do this:

@user.ratings.find_by_comment_id(7)

The SQL will look something like this:

SELECT * FROM ratings WHERE user_id = 1 AND comment_id = 7

So, even though you've referenced the #ratings association, ActiveRecord only ends up loading one row from the database, not everything associated to the specified user. The same rules apply to the #comments association, although the SQL queries will be somewhat more complex.

Excellent, thanks for your answer!

if you are displaying lets say 20 comments a page then you are going to repeat this @user.ratings.find_by_comment_id(?) 20 times ... instead it would be nice if you can load it once on the server end ... lets say an array of comments posted by the user and then while displaying we can check if the comment is in the array or not and can show thumbs up and down accordingly ... sorry if it doesn't make any sense :-s

5 Posts
Login to add your message