如何根据关联对象的最后记录列对ActiveRecord 关系进行排序

How To Order ActiveRecord Relation Based on Column Of Last Record Of Associated Object

我有以下2个型号:

Client
has_many :cases

Case
belongs_to :client

假设我有 2 个客户 c1 和 c2。
c1有1个case,c2有2个case

c1    = Client.create(name: 'C1')
c2    = Client.create(name: 'C2')
case1 = Case.create(type: 'Normal', client: c1)
case2 = Case.create(type: 'Normal', client: c2)
case3 = Case.create(type: 'High', client: c2)

我想获取所有客户并按每个客户的最后一个案例的类型排序 asc/desc。 因此,如果我按 asc 排序,我应该得到 'c1' 然后是 c2 的结果。如果我按 desc 排序,我应该得到 'c2' 然后 'c1' 的结果。以下是我到目前为止尝试过的方法。

Client.includes(:cases).order('cases.type asc') # => 'C2,C1'
Client.includes(:cases).order('cases.type desc') # => 'C2,C1'

因为 c2 也有类型 'Normal' 的情况,我认为查询似乎是先找到客户,然后再做类似 client.cases 的事情。然后,我认为它只对每个客户端下的案例进行排序,而不是跨客户端对案例进行排序。
我认为我的解释有点混乱。如果你有,请给我一个问题。谢谢

我更改了列 'case_type' 而不是 'type' 因为我们不能在我们的 table.

中使用列类型

要按客户案例的最后记录的案例类型对数据进行排序,请试试这个。

对于 ASC

Client.includes(:cases).sort_by{|m| m.cases.last.case_type}

对于 DESC

 Client.includes(:cases).sort_by{|m| m.cases.last.case_type}.reverse

您可以像这样为具有多个关联的对象设置默认排序器:

has_many :cases, -> { order 'type asc' }

这样,案件将始终 return 有序。因此,您可以使用 sort_by 为您的客户设置自定义排序,调用最后一个案例(并确信这些案例已排序),例如:

Client.includes(:cases).sort_by { |c| c.cases.last.type }

在我看来,一切都很好。 您的订单声明仅确保 typecase_type 的订单。 数据库可以return

Normal, C1
Normal, C2
High, C2

Normal, C2
Normal, C1
High, C2

对于 cases.type asc

type 等于您未指定时会发生什么。 Rails 将 return 您的对象在数据库 return 中的顺序记录。

如果您不想再给您下单,您必须指定订单,例如:

Client.includes(:cases).order('cases.type asc, clients.name asc')

编辑:

要仅对最后一条相关记录进行排序,您可以使用子选择:

Client.select('(SELECT cases.type from cases where cases.client_id=clients.id ORDER BY cases.id desc LIMIT 1) as case_type_name, *').order('case_type_name asc')