Правильный способ установить эти ассоциации:
class Order < ApplicationRecord
belongs_to :item
# This references items.category_id
has_one :category, through: :item
end
class Item < ApplicationRecord
has_many :orders
belongs_to :category
end
class Category < ApplicationRecord
has_many :item, through: :orders
has_many :orders
end
Вы хотите удалить столбец orders.category_id
(если он существует) и использовать косвенную связь через таблицу элементов, чтобы избежать дублирования.Семантика belongs_to
и has_one
может сбивать с толку, но belongs_to
предполагает, что внешний ключ находится на этой модели (заказы), тогда как has_one
размещает его на других моделях таблица (элементы).
Это позволит вам присоединиться к / включить / eager_load ассоциации с:
irb(main):002:0> Order.joins(:category)
Order Load (1.4ms) SELECT "orders".* FROM "orders" INNER JOIN "items" ON "items"."id" = "orders"."item_id" INNER JOIN "categories" ON "categories"."id" = "items"."category_id" LIMIT $1 [["LIMIT", 11]]
И, как вы можете видеть, Rails будет обрабатывать присоединение к таблице присоединения (элементы)автоматически.
Если вы хотите, чтобы обе ассоциации были загружены, вы можете использовать хеш или просто перечислить оба:
Order.eager_load(item: :category)
Order.eager_load(:item, :category)