【问题标题】:Sort records based on number of rows in another table - Rails根据另一个表中的行数对记录进行排序 - Rails
【发布时间】:2014-06-10 20:04:55
【问题描述】:

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

提交模式

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 中实现?

【问题讨论】:

  • 在纯 SQL 中,这类似于 select userID, users.*, count(submissionID) from users INNER JOIN submission on Users.userID = submission.UserID group by userID order by count(*) desc 但我不确定 ruby​​ 是如何做到这一点的......

标签: sql ruby-on-rails activerecord


【解决方案1】:

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


使用 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 都会为该用户增加/减少以反映更改。

【讨论】:

  • 感谢您的详尽解释。信息量很大。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-09-30
  • 1970-01-01
  • 1970-01-01
  • 2018-11-15
  • 2023-04-01
  • 2018-07-13
  • 1970-01-01
相关资源
最近更新 更多