Reputation: 19863
Lets say I have Posts
with many Comments
Is it possible to do an ActiveRecord query to to get the Posts ordered by most comments?
I'm surprised this relatively common query in plain old MySQL doesn't seem to have an easy answer in AR. Yes you can use a counter_cache, but this isn't really recreating the original query.
What am I missing?
Taking it one step further. What if Posts
have many Comments
which have many Likes
. Is it possible to get Posts with the most Likes in aggregate?
Thanks!
Upvotes: 3
Views: 752
Reputation: 29960
I supose you can do something like this using arel::
comments= Comment.arel_table
posts= Post.joins(:comments).order(comments[:id].count)
Though, I am not sure if this is the right way to do it. You will have to try it by yourself.
Upvotes: 0
Reputation: 2260
Pretty sure you can do something like this as well if you want:
posts = Post.find(:all, :include => 'comments')
posts.sort { |a,b| b.comments.count <=> a.comments.count }
Upvotes: 0
Reputation: 21180
As you say, counter_cache seems to be the closest to doing it the "rails way". So far I have not encountered any AR defined methods for this specific purpose but this is the closest thing to it that I have seen:
@posts = Post.select("posts.*, COUNT(comments.id) AS count_comments").joins("LEFT OUTER JOIN comments ON posts.id = comments.post_id").group("posts.id").order("count_comments DESC")
@posts.each do |post|
puts "Comments: #{post.count_comments}"
end
Custom select to include the count_comments attribute. Joins instead of include because include will override the select syntax. Custom joins syntax instead of merely :comments because otherwise it will be an inner join which will prevent posts without comments to be retrieved.
This is basically writing the entire SQL syntax yourself, but still... it works :)
Upvotes: 1