根据另一个表中的行数对Rails进行排序

时间:2014-06-10 20:04:56

标签: sql ruby-on-rails activerecord

所以我有一个用户表,在我的关系中,我已经定义用户有很多提交和提交属于用户。我想根据用户提交的数量对用户表进行排序。

提交模式

class Submission < ActiveRecord::Base
    belongs_to :user
end

用户模型

class User < ActiveRecord::Base
    has_many :submissions, dependent: :destroy
end

我离开的目的是,我能够使用此查询获取用户提交的提交数量

Submission.all.count(:group => "user_id")

以此为例,我能够获得具有特定ID的用户提交的数量

{1=>3, 2=>5} 

我想要一个排序的用户表,其中用户的提交数量最多。如何在rails activerecord中实现?

1 个答案:

答案 0 :(得分:1)

你可以通过两种方式做你想做的事:


使用join,group by和count by count

User.select("COUNT(*) AS count_all, submissions.user_id AS submissions_user_id")
    .joins('LEFT JOIN submissions ON submissions.user_id = users.id')
    .group('submissions.user_id')
    .order('COUNT(submissions.user_id) DESC')

这将生成以下sql:

SELECT COUNT(*) AS count_all, submissions.user_id AS submissions_user_id FROM "users" LEFT JOIN submissions ON submissions.user_id = users.id GROUP BY submissions.user_id  ORDER BY COUNT(submissions.id) DESC

LEFT JOIN也会为用户提供0次提交(如果你有这种情况)


使用counter_cache

在这种情况下,最有效的查询解决方案是使用counter_cache 这将使您能够运行如下查询:

User.order('submissions_count DESC')

转换为:

SELECT * FROM users ORDER BY submissions_count DESC

<强> !!!如果要实现此功能,尤其是在生产中,请在启动之前备份数据库。 !!!

阅读counter_cache个文档,了解它是什么以及它如何为您提供帮助。

在名为users的{​​{1}}表格上添加新列。

submissions_count

修改您的提交模型并添加counter_cache。

class AddSubmissionsCountToUsers < ActiveRecord::Migration
  def change
    add_column :users, :submissions_count, :integer, default: 0
    add_index  :users, :submissions_count
  end
end

如果您有生产数据库更新submissions_count以反映现有提交的数量:

class Submission < ActiveRecord::Base
  belongs_to :user, counter_cache: true
end

每次用户创建/销毁订阅时,submissions_count将为该用户递增/递减以反映更改。