所以我有一个用户表,在我的关系中,我已经定义用户有很多提交和提交属于用户。我想根据用户提交的数量对用户表进行排序。
提交模式
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中实现?
答案 0 :(得分:1)
你可以通过两种方式做你想做的事:
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 这将使您能够运行如下查询:
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将为该用户递增/递减以反映更改。