Rails Query для присоединения дочернего класса к родительскому классу через сквозной класс - PullRequest
0 голосов
/ 15 января 2020

У меня есть следующий класс

class Order
   has_many :order_issues, through: :order_deliveries, inverse_of: :order
end

class OrderDelivery
   has_many :order_issues, as: :issuable, inverse_of: :order_delivery
   belongs_to :order, inverse_of: :order_deliveries
end

class OrderIssue
   belongs_to :order, inverse_of: :order_issues
   belongs_to :order_delivery, inverse_of: :order_issues
end

Когда я пытаюсь

Order.joins(:order_issues).to_sql 


SELECT orders.* 
FROM orders 
INNER JOIN order_deliveries 
   ON order_deliveries.order_id = orders.id 
INNER JOIN order_issues 
   ON order_issues.issuable_id = order_deliveries.id 
      AND order_issues.issuable_type = 'OrderDelivery' 

Он работает как задумано. Однако, когда я пытаюсь

OrderIssue.joins(:order).to_sql

SELECT order_issues.id 
FROM order_issues 
INNER JOIN orders 
    ON orders.id = order_issues.order_id

Почему это отличается? В идеале я бы хотел, чтобы запрос SQL, который был бы похож на приведенный ниже, дал бы OrderIssue активных записей

SELECT order_issues.* 
FROM order_issues 
INNER JOIN order_deliveries ON order_issues.issuable_id = order_deliveries.id 
       AND order_issues.issuable_type = 'OrderDelivery'
INNER JOIN orders 
    ON order_deliveries.order_id = orders.id 

1 Ответ

1 голос
/ 15 января 2020

inverse_of используется только для избежания дублирования поиска идентичных записей; это не меняет поведение разрешения отношения ActiveRecord.

В этой ситуации установка has_many :order_issues без опции :through может показаться правильным и даст вам запрос, который вы ищете, потому что OrderIssue напрямую belongs_to :order. OrderDelivery также должны быть обновлены соответственно.

class Order
  has_many :order_issues
  has_many :order_deliveries
end

class OrderDelivery
  belongs_to :order
  has_many :order_issues, through: :order
end

class OrderIssue
  belongs_to :order
  has_many :order_deliveries, through: :order
end
...