我正在努力让Ruby on Rails正确执行此查询...总之:通过该关系中的最新记录加入has_many
关系,但only可以然后应用过滤器/选择该关系。
这是捕捉我奋斗的一个超级简单的变体:
假设我有一个Employees
表和一个Employments
表。一个employee has_many employments
。 employment
的status
为:active
或:inactive
。
class Employee < ActiveRecord::Base
has_many :employments
end
class Employment < ActiveRecord::Base
belongs_to :employee
end
[为了简单起见,假设有一个employee
:丹和他有两个employments
:一个旧的(由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)
因此,实际上,您可以说:“丹工作了两次,目前正在积极工作。”
我想要的是Rails查询,它说:“找到不活跃的员工”。这应该返回一个空集,因为Dan的latest
employment
为:active
。所以我不能只做:Employee.joins(:employments).where(employments: { status: :inactive })
,因为它会与old employment
匹配并因此返回Dan employee
记录。[我需要说一句:“仅根据最新
雇用记录来查找处于非活动状态的员工”。但是我不知道如何在Rails中做到这一点。
[我觉得我想念一些东西...应该很简单...但是我无法弄清楚。
谢谢!
我正在努力让Ruby on Rails正确执行此查询……简而言之:加入has_many关系,但只能通过该关系中的最新记录,然后可以对该条件应用过滤器/选择。 。
我能想到的最简单的解决方案(基于代码的复杂性)是首先获取具有其最大值的工作ID,然后使用结果组合一个新查询。
在具有大量行的应用程序中,我为完全相同的问题付出了很多努力,在尝试了各种新颖的解决方案(如横向联接和子查询)之后,性能最好,到目前为止最简单的解决方案是在表中添加外键指向最新行,并使用关联回调(或db trigger)设置外键。
[摆弄了一会儿(并尝试了所有大家提出的所有建议,再加上其他建议),我想到了这个。它有效,但可能不是最优雅的。
+ 1为@max的答案。
由于标题包括ARel
。以下示例适用于您的示例:
我认为您可以先获取这些最大日期,以确保不会获取旧记录,然后仅过滤所需的状态。这是执行第一部分的示例]
一种替代方法是使用LATERAL JOIN,这是Postgres 9.3+的特定功能,可以描述为类似SQL foreach循环的事物。