Как заставить ассоциации работать в построенных и несохраненных объектах?
Скажем, у меня есть что-то вроде:
@order = Order.new(status: :pending)
@item = @order.items.build(title: "Shirt")
Когда я пытаюсь позвонить @item.order
, я получаю сообщение об ошибке не найден, я думаю, потому что он все еще не сохранен для БД, но как он может указывать на построенный объект без сохранения каких-либо объектов?
@item.order # Not Found - Tries to fetch from the DB
Ответы
Ответ 1
Чтобы выполнить эту работу, вы должны сообщить ассоциации order
модели вашего объекта, что она является обратной вашей ассоциации items
или вы заказываете модель и наоборот:
Вот так:
class Item < ActiveRecord::Base
belongs_to :order, inverse_of: :items
end
class Order < ActiveRecord::Base
has_many :items, inverse_of: :order
end
Таким образом, ваши ассоциации будут настроены правильно даже до сохранения в базе данных.
РЕДАКТИРОВАТЬ: Если вы этого не хотите, вы всегда можете назначить ассоциацию явно:
@item = @order.items.build(title: "Shirt")
@item.order = @order
или в одной строке:
@item = @order.items.build(title: "Shirt", order: @order)
Ответ 2
Я тестировал это в Rails 4.0.1, и похоже, что использование inverse_of
больше не требуется, поскольку ассоциации выведены правильно. Он был рассмотрен в этой фиксации: https://github.com/rails/rails/pull/9522
Стоит отметить, что до сих пор нет решения для отношений has_many through:
.
Ответ 3
То, что у @order
еще нет идентификатора. Поэтому при вызове @order.items.build
элемент имеет поле nil
в order_id
и, следовательно, не может найти нужный вам порядок.
Я предлагаю вам использовать вложенные атрибуты, чтобы сохранить некоторые связанные записи вместе.