ruby 如何为ActiveRecord连接应用附加条件

vyu0f0g1  于 2023-08-04  发布在  Ruby
关注(0)|答案(2)|浏览(101)

假设我试图计算一段时间内每个部门的事故计数。我有两张table。我尝试使用ActiveRecord来获取答案,结果如下所示

class Division < ApplicationRecord
  has_many :accidents

end

class Accident < ApplicationRecord
  belongs_to :division

end

Division.left_joins(:accidents).where('accidents.occurred_at > ?', Time.now - 1.year).group(:name).count

字符串
在本例中,ActiveRecord生成以下SQL

SELECT COUNT(accidents.id) AS "count_all", "divisions"."name" AS "divisions_name"
FROM "divisions"
LEFT OUTER JOIN "accidents" ON "accidents"."division_id" = "divisions"."id"
WHERE (accidents.occurred_at > '2022-07-30 20:56:10.178153')
GROUP BY "divisions"."name"


这里的问题是,如果某个除法的意外计数为0,我们将不会在查询结果中看到它,所以我需要这样的SQL

SELECT COUNT(accidents.id) AS "count_all", "divisions"."name" AS "divisions_name"
FROM "divisions"
LEFT OUTER JOIN "accidents" ON "accidents"."division_id" = "divisions"."id" and accidents.occurred_at > '2022-07-30 20:56:10.178153'
GROUP BY "divisions"."name"


是否可以指定一些加入的附加条件?我知道我们可以为has_many关系指定附加条件,但它将是一个静态条件。我希望它是动态的,取决于用户的请求参数
我试图避免使用原始SQL作为连接条件e.q.

Division.joins("LEFT OUTER JOIN accidents ON accidents.division_id = divisions.id
and (accidents.occurred_at > '2022-07-30 20:56:10.178153'").group(:name).count('accidents.id')

nhn9ugyo

nhn9ugyo1#

如何在JOIN中使用作用域来简化最终查询?

class Division < ApplicationRecord
  scope :with_accidents_from, ->(occurred_at) do
    joins_query =
      sanitize_sql([
        'LEFT OUTER JOIN accidents ON accidents.division_id = divisions.id AND accidents.occurred_at > ?',
        occurred_at
      ])

    joins(joins_query)
  end
end

字符串
然后呢

Division.with_accidents_from(1.year.ago).group(:name).count('accidents.id')

hm2xizp9

hm2xizp92#

我会尝试与这样的作用域关联

# in the model
class Division < ApplicationRecord
  has_many :accidents
  has_many :recent_accidents, class_name:  'Accident', 
                              foreign_key: 'division_id',
                              -> { where occurred_at: (1.year.ago..) }

字符串
并会这样使用它:

Division.left_outer_joins(:recent_accidents)
        .group(:name)
        .count('accidents.id')

相关问题