0

I have the following class

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

When I try

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' 

It works as intended. However when I try

OrderIssue.joins(:order).to_sql

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

Why is it different? I would ideally want the SQL query that would something look like below to give the OrderIssue active records

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 
Sathish
  • 409
  • 8
  • 24

1 Answers1

1

inverse_of is only used to avoid duplicate retrieval of identical records; it does not change the behavior of ActiveRecord Relation resolution.

In this situation, setting has_many :order_issues without the :through option would seem to be the correct usage and would get you the query you're looking for because OrderIssue directly belongs_to :order. OrderDelivery should also be updated accordingly.

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
coreyward
  • 77,547
  • 20
  • 137
  • 166
  • `orders` do not have `order_issues` directly. They have through `order_deliveries` as `issuable`. I have updated the code in case it was confusing before. – Sathish Jan 15 '20 at 18:56
  • 2
    @Sathish Then `OrderIssue` should `belong_to :order_delivery`, not `:order`, and could also `has_one :order, through: :order_delivery`. – coreyward Jan 15 '20 at 19:19