如何根据关联对象的最后记录列来订购ActiveRecord关系

时间:2016-09-14 08:04:52

标签: sql ruby-on-rails activerecord queryinterface

我有两个模型如下:

Client
has_many :cases

Case
belongs_to :client

假设我有2个客户c1& C2。
c1有1个案例,c2有2个案例。

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的事情。然后,我认为它只对每个客户下的案件进行排序,并且不会通过客户订购案件 我认为我的解释有点令人困惑。如果有的话,请给我一个问题。感谢。

3 个答案:

答案 0 :(得分:0)

我更改了列' case_type'而不是'类型'因为我们不能在表中使用列类型。

要根据客户案例的最后记录的案例类型对数据进行排序,请尝试此操作。

对于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

答案 1 :(得分:0)

您可以为具有多个关联设置默认的ordcer,如下所示:

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

这样,案例将始终按顺序返回。因此,您可以使用sort_by在客户端上设置自定义排序,调用最后一个案例(并确信案例已订购),例如:

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

答案 2 :(得分:0)

在我看来,每件事都很好。 您的订单声明仅确保typecase_type的顺序。 数据库可以返回

Normal, C1
Normal, C2
High, C2

Normal, C2
Normal, C1
High, C2

代表cases.type asc

type相等时你应该怎么办? Rails将按照数据库返回记录的顺序返回对象。

如果您不想再订购,则必须指定订单,例如:

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')