gpt4 book ai didi

ruby-on-rails - 如何在 Ruby on Rails 中构建一个查询,该查询仅加入一个 has_many 关系的最大值并在该关系上包含一个选择过滤器?

转载 作者:行者123 更新时间:2023-12-04 00:01:27 25 4
gpt4 key购买 nike

我正在努力如何让 Ruby on Rails 正确执行此查询...简而言之:加入 has_many 关系但 通过最近的记录在该关系中,然后可以对该关系应用过滤器/选择。

这是一个 super 简单的变体,可以捕捉到我的挣扎:


假设我有一个 Employees 表和一个 Employments 表。 employee has_many 就业employmentstatus:active:inactive

class Employee < ActiveRecord::Base
has_many :employments
end

class Employment < ActiveRecord::Base
belongs_to :employee
end

为了简单起见,假设有一个 employee:Dan 和他有两个 employees:一个旧的(由 created_at 提供)即 :inactive 和一个新的 :active

dan = Employee.create(name: 'Dan')
Employment.create(employee: dan, created_at: 2.years.ago, status: :inactive)
Employment.create(employee: dan, created_at: 3.months.ago, status: :active)

因此,实际上,您可以说:“Dan 工作了两次,目前正在积极工作。”

我想要的是 Rails 查询语句:“找到不活跃的员工”。这应该返回一个空集,因为 Dan 的 latest employment:active。所以我不能只做: Employee.joins(:employments).where(employments: { status: :inactive }) 因为它会匹配 old employment 并因此返回 Dan employee 记录。

我需要一种说法:“仅根据最近的就业记录查找不活跃的员工”。

但我不知道如何在 Rails 中做到这一点。

我觉得我错过了什么……应该很简单……但我想不通。

谢谢!

最佳答案

我在一个包含大量行的应用程序中遇到了完全相同的问题,在尝试了各种新颖的解决方案(如横向连接和子查询)之后,性能最佳且迄今为止最简单的解决方案就是向指向最新行并使用关联回调(或 db trigger)设置外键的表。

class AddLatestEmploymentToEmployees < ActiveRecord::Migration[6.0]
def change
add_reference :employees, :latest_employment, foreign_key: { to_table: :employments }
end
end

class Employee < ActiveRecord::Base
has_many :employments, after_add: :set_latest_employment
belongs_to :latest_employment,
class_name: 'Employment',
optional: true

private
def set_latest_employment(employment)
update_column(:latest_employment_id, employment.id)
end
end

Employee.joins(:latest_employment)
.where(employments: { status: :active })

如果关联记录的数量像我的情况一样巨大,那真的很出色,因为您可以急切地加载最新记录,而不会在加载整个 has_many 关联时出现内存问题。

关于ruby-on-rails - 如何在 Ruby on Rails 中构建一个查询,该查询仅加入一个 has_many 关系的最大值并在该关系上包含一个选择过滤器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60551675/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com