ruby-on-rails 如何根据另一个表中的数据对ruby集合进行排序?

svmlkihl  于 2023-03-04  发布在  Ruby
关注(0)|答案(1)|浏览(138)

我有一个过滤后的公司列表:

#<ActiveRecord::Relation [#<Company id: 483, name: "Apple", description: "Apple Inc. is an American multinational technology...", social_website: "https://www.apple.com/">, #<Company id: 482, name: "Ceres Technology", description: "", social_website: "cerestech.co">]>

下面的表格显示了每家公司的追随者数量:

query_chain.each do |company|
  total_followers_period = Follow.where('followable_type = ? AND followable_id = ? AND created_at > ?', "Company", company.id,1.week.ago).count
  total_followers_companies[company.id] =  total_followers_period
end

我需要根据公司列表中的行数将其排序到下表中。
我试着返回一个数组,它工作,但我需要返回活动记录收集排序的追随者数量如下表。

v1uwarro

v1uwarro1#

这里你的错误在于你应该用SQL来思考的时候却用Ruby来思考。
在SQL中,您将按www.example.com分组company.id,并按连接表中的行数计数排序。

Company.joins(:follows)
       .group(:id)
       .order(Follow.arel_table["*"].count.desc)

如果你想把范围缩小到最近一周的次数,你可以通过在聚合表达式中添加一个FILTER来实现:

class Company < ApplicationRecord
  has_many :follows, as: :followable

  def self.order_by_follows
    f = Follow.arel_table
    left_joins(:follows)
      .group(:id)
      .order(
        # COUNT(follows.*) FILTER WHERE(follows.created_at < ?)
        f[Arel.star].count.filter(f[:created_at].gt(1.week.ago.to_date)).desc
      )
  end 
end

FILTER is available on Postgres and SQLite并过滤进入聚合函数的行。在其他数据库上,您可以执行自定义连接或子查询来获得相同的结果。
如果您使用的是Rails 7之前的版本,则必须使用SQL字符串istead:

class Company < ApplicationRecord
  has_many :follows, as: :followable

  def self.order_by_follows
    f = Follow.arel_table
    left_joins(:follows)
      .group(:id)
      .order(
        Arel.sql(
          "COUNT(follows.*) FILTER WHERE(follows.created_at < #{1.week.ago.to_date}) DESC"
        )
      )
  end 
end

相关问题