Justin
Justin

Reputation: 4940

Rails db query to find and sort posts

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

Answers (2)

Gjaldon
Gjaldon

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

Peter de Ridder
Peter de Ridder

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

Related Questions