开发者

Rails order by associated object number

开发者 https://www.devze.com 2023-01-10 15:57 出处:网络
The title of this question might be a bit off but its the cl开发者_JAVA技巧osest I could get to what I am trying to do.

The title of this question might be a bit off but its the cl开发者_JAVA技巧osest I could get to what I am trying to do.

I have a Products model which has_many Comments. I am looking to come up with a way to grab the top 10 Products with the most comments. Is this possible?

At the moment I have:

Product.find(:all, :limit => 10)

This gets me my 10 products, but it obviously does not consider how many comments each product has.

Cheers

Eef


If you have a counter cache column on Product for Comment then you can do this with a simple :order_by on that column.

Edit: Taking animal's comment into account:

class Product < ActiveRecord::Base
  has_many :comments,
    :counter_cache => true
end

You will need a column on products called comments_count:

add_column :products, :comments_count, :integer, :null => false, :default => 0


Alternatively if you don't want to alter your model you can use find_by_sql to specify a subselect which will tell you how many comments each product has and order by that. E.g.

Post.find_by_sql("SELECT products.*
  FROM products, (SELECT COUNT(*) 
    FROM comments WHERE comments.product_id = products.id) AS product_comment_count
  ORDER BY product_comment_count DESC
  LIMIT 10")

You might need to adjust the syntax to be specific to whichever RDBMS you are using.


Try this:

Product.all(:select=> "products.*, COUNT(products.id) AS comments_count",
            :joins => :comments, 
            :group => "products.id", 
            :order => "comments_count",
            :limit => 10)

Result is sorted by the comment count and you can access the comments_count as follows:

@products.each do |product|
  p product.comments_count
end

Make sure you have indexed the product_id column in the comments table.

Note:

I would use the counter_cache feature for this requirement(as suggested by @tadman).

0

精彩评论

暂无评论...
验证码 换一张
取 消