ActiveRecord订单嵌套项

时间:2019-02-22 14:43:51

标签: ruby-on-rails ruby activerecord

我有票务和服务模型

class Ticket < ApplicationRecord
  belongs_to :medic
  has_and_belongs_to_many :services

  validates_presence_of :services
end

class Service < ApplicationRecord
  has_and_belongs_to_many :tickets
end

,服务模型具有字段codename。 因此,services表具有类似

的记录
id |  code  | name 
1  |  5.1   | value 1
2  |  5.2   | value 2
3  |  6.1   | value 3
and so on

是否可以进行查询以获取按名称排序的票证,包括按 code 排序的服务(例如)?

Ticket.includes(:services, :medic)
        .order(date: :desc, created_at: :desc)
        .where(where_conditions)    (works fine, but without services order)

我使用Sequelize确实做到了这一点,但不知道如何使用ActiveRecord来完成。我尝试过

Ticket.includes(:services, :medic)
        .order(date: :desc, created_at: :desc, "services.code": :desc)
        .distinct
        .where(where_conditions)

但是得到了

ActionView::Template::Error (SQLite3::SQLException: no such column: tickets.services.code: SELECT DISTINCT "tickets".* FROM "tickets" WHERE "tickets"."date" BETWEEN ? AND ? AND "tickets"."enabled" = ? ORDER BY "tickets"."date" DESC, "tickets"."created_at" DESC, "tickets"."services.code" DESC):

2 个答案:

答案 0 :(得分:1)

您可以通过字符串将确切的order子句传递到ActiveRecord order方法中:

Ticket.includes(:services, :medic).references(:services)
      .order('tickets.date desc, tickets.created_at desc, services.code desc')
      .distinct
      .where(where_condition)

请注意,我还添加了references(:services)来通知ActiveRecord您想在此表上放置一些条件或其他子句,否则ActiveRecord默认情况下会创建单独的数据库查询,而无需使用join

答案 1 :(得分:1)

有关更多“使用API​​”的解决方案,您可以使用Arel:

ticket = Ticket.arel_table
service = Service.arel_table

Ticket.includes(:services, :medic).references(:services)
      .order(ticket[:date].desc, ticket[:created_at].desc, service[:code].desc)
      .distinct
      .where(where_condition)

或者:

Ticket.includes(:services, :medic).references(:services)
      .order(Ticket.arel_table[:date].desc, Ticket.arel_table[:created_at].desc, Service.arel_table[:code].desc)
      .distinct
      .where(where_condition)