So I'm implementing an up/down voting mechanism for which I'm generating a model. So far I understand that a video (what will be voted on) has one vote_count, and vote_count belongs to videos. However, I also want to track in my vote_count database the user that has voted on the video. Does that mean that a vote_count has many users, and that a user belongs to a vote_count?
Asked
Active
Viewed 176 times
2 Answers
5
It may be easier to track the votes as independent records, such as this:
class VideoVote < ActiveRecord::Base
belongs_to :user
belongs_to :video
end
class User < ActiveRecord::Base
has_many :video_votes
has_many :voted_videos,
:through => :video_votes,
:source => :video
end
class Video < ActiveRecord::Base
has_many :video_votes,
:counter_cache => true
has_many :voted_users,
:through => :video_votes,
:source => :user
end
If you have people voting up and down, you will need to track the net vote total somehow. This can be tricky, so you may want to look for a voting plugin.

tadman
- 208,517
- 23
- 234
- 262
-
1+1. I was in the middle of writing the same post. What you described, @Justin, would only allow a user to vote on one video. You need to track (a) which user voted on which video, (b) how they voted (up or down) and (potentially) (c) when they voted. – Nuby Mar 17 '11 at 17:32
-
Thanks! What is `:counter_cache => true`? – Justin Meltzer Mar 17 '11 at 17:36
-
Also two more things: 1. Just be sure, I would need to add `has_many :videos` to the user model, and `belongs_to :user` to the video model? And secondly, would I make one upvote method and one downvote method in the controller? – Justin Meltzer Mar 17 '11 at 17:39
-
The counter cache is a way to track the number of records created through that relationship without having to run a `COUNT()` on them each time. It's not practical to display large lists of things without it. [Here's a demo from Railscasts](http://railscasts.com/episodes/23-counter-cache-column) In this case you would have a `video_votes_count` column on your `videos` table to capture the number of votes cast. – tadman Mar 17 '11 at 17:40
-
If your videos `belong_to` users, then yes, you can have a user to video relationship like that and it won't interfere with the voting structure. For up/down votes, you may make two different controller actions, but one with a parameter that's set by your routing is often easier, perhaps something like: `match '/videos/:id/vote_down', :to => 'videos#vote', :vote => -1` – tadman Mar 17 '11 at 17:44
-
thanks, and I can just pass vote to the controller action and it'll have it as equal to -1? – Justin Meltzer Mar 17 '11 at 17:54
-
Hold on a second. After watching the railscast episode you linked to, shouldn't `:counter_cache => true` go in the VideoVote model after `belongs_to :video`? – Justin Meltzer Mar 17 '11 at 18:55
-1
Am I missing something here? Why not assign a netVoteTally
as a property of Videos
. Initialize it to zero when video.new
is called and have incNetVideoTally
and decNetVideoTally
methods that are accessible outside the video method? Just my $0.02.

Perry Horwich
- 2,798
- 3
- 23
- 51
-
I want to be able to know which user voted up the video, and so that requires its own model with rich many-to-many associations. It also gives me the most flexibility in different things I could display to the user, such as all the users that have voted on a video, or all the videos that a voter has voted on. – Justin Meltzer Mar 17 '11 at 18:58
-
Seems I put my answer in the wrong spot in this thread. I was more responding to tadman's comment on his own good answer where he mentions that tracking net vote total could be tricky. Apologies. – Perry Horwich Mar 17 '11 at 19:53