你可以通过两种方式做你想做的事:
使用 join、group by 和 order 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 表上添加一个名为 submissions_count 的新列。
class AddSubmissionsCountToUsers < ActiveRecord::Migration
def change
add_column :users, :submissions_count, :integer, default: 0
add_index :users, :submissions_count
end
end
修改您的提交模型并添加 counter_cache。
class Submission < ActiveRecord::Base
belongs_to :user, counter_cache: true
end
如果您有一个生产数据库更新 submits_count 以反映现有提交的数量:
User.find_in_batches do |group|
group.each do |user|
user_submissions_count = Submission.where(user_id: user.id).count // find how many subscription a user has
user.update_column(:submissions_count, user_submissions_count)
end
end
每次用户创建/销毁订阅时,submissions_count 都会为该用户增加/减少以反映更改。