按相关记录的数量排序记录

时间:2012-07-07 10:45:54

标签: sql scope ruby-on-rails-3.2

用户可以提交资源并发表评论。

我想通过选择已提交资源和评论的用户以及从提交了最多资源和评论的用户那里订购结果来向最“活跃”的用户展示。

**Resource**
has_many :users, :through => :kits
has_many :kits
belongs_to :submitter, class_name: "User"

**User**
has_many :resources, :through => :kits
has_many :kits
has_many :submitted_resources, class_name: "Resource", foreign_key: "submitter_id"

**Kits**
belongs_to :resource
belongs_to :user

**Comments**
belongs_to :user

我是Rails中这种sql的新手。如何获得此记录集?

1 个答案:

答案 0 :(得分:2)

首先,您需要将评论关联添加到用户模型:

has_many :comments

有了这个,最简单的解决方案就是这样做:

User.all.sort do |a,b|
   (a.submitted_resources.count + a.comments.count) <=> (b.submitted_resources.count + b.comments.count)
end

这会变得很慢,所以如果你想做得更好,你会想要添加计数器缓存。在迁移中:

def up
  add_column :users, :submitted_resources_count, :integer
  add_column :users, :comments_count, :integer

  User.reset_column_information

  User.find_each do |u| 
    u.update_attributes! \
      :submitted_resources_count => u.submitted_resources.count,
      :comments_count => u.comments.count
  end
end

def down
  add_column :users, :submitted_resources_count
  add_column :users, :comments_count
end

运行此迁移后,您可以将原始查询更改为:

User.select('*, (submitted_resources_count + comments_count) AS activity_level').order('activity_level DESC')

这将非常有效地以正确的顺序返回所有用户,并且作为奖励,每个用户将拥有一个名为activity_level的只读属性,该属性将提供准确的提交资源+评论数。