Reputation: 4940
My app has designs that users can like (vote, using acts_as_voteable). To find a design's like count in the view, you use
@design.votes.count
I'm making a popular page to showcase the most popular designs based on the number of votes they have. I only want designs that has at least 5 votes to them. Right now, I had that in the view but I want to push that into the controller. My controller, thus far, looks like this which shows all the designs and sorts them in order of most votes.
def popular
@designs = Design.all
@designs.sort! {|t1, t2| t2.votes.count <=> t1.votes.count}
end
Now i just want to make sure the designs have a minimum vote count of 5.
Previously, I was doing this the wrong way and putting it in my view by putting this inside my Design loop
<% if design.vote.count > 5 %>
...
<% end %>
Thanks!
Upvotes: 4
Views: 171
Reputation: 5644
First of all, the behavior you want is better defined in the Design model and not in the controller since it deals with data. So in your Design model, add the following code:
scope :most_popular, -> do
results = select {|design| design.votes.count > 4 }
results.sort! {|t1, t2| t2.votes.count <=> t1.votes.count}
end
Adding the two scope methods above in your Design model, you could do this in your controller code:
def popular
@designs = Design.most_popular
end
Your controller code ends up being a lot cleaner and you have scope methods that you can reuse anywhere else you need them. :)
Hope that helps!
Upvotes: 4
Reputation: 2399
You can use a having() clause. See: http://guides.rubyonrails.org/active_record_querying.html#having
For example: Design.joins(:votes).group('votes.design_id').having('votes.count > 5').order('votes.count')
Edit
You can also just use a where clause. For example, for the first design:
Design.first.votes.where('count > 5')
Example for multiple designs:
Design.all.map{ |a| a.votes.where('count > 5').count }.sort! # returns a sorted array with all vote counts
Upvotes: 2