Переопределить вложенные атрибуты в рельсах
что происходит, когда я переопределяю метод вложенных атрибутов в рельсах. Например,
class Order
has_many :line_items
accepts_nested_attributes_for :line_items
def line_item_attributes=(attr)
# what can I do here.
end
end
class LineItem
belongs_to :order
end
В приведенном выше коде
- Внутри метода
line_item_attributes=
могу ли я добавить/изменить/удалить позиции заказа?
- Когда вызывается
line_items_attributes=
, если я вызываю @order.save(params)
?
Ответы
Ответ 1
- Да, вы могли бы. Просто позвоните
assign_nested_attributes_for_collection_association(:line_items, attributes, mass_assignment_options)
когда вы закончите.
Проверьте источник также: # File activerecord/lib/active_record/nested_attributes.rb, line 263
Сохранение
Все изменения в моделях, включая уничтожение отмеченных уничтожения, сохраняются и уничтожаются автоматически и атомарно, когда родительская модель сохраняется. Это происходит внутри транзакции инициированный родителями метод сохранения. Видеть ActiveRecord:: AutosaveAssociation.
Я не думаю, что это хорошая идея, чтобы перезаписать этот метод. Я бы добавил ваш код к after_save
hook.
Ответ 2
Используйте псевдоним
В Rails 4 вы можете переопределить и вызвать super
.
В более ранних версиях вы можете использовать Ruby alias
:
class Order
has_many :line_items
accepts_nested_attributes_for :line_items
# order of arguments is new_name, existing_name
alias :original_line_items_attributes= :line_items_attributes=
def line_items_attributes=(attrs)
modified_attributes = my_modification_method(attrs)
self.original_line_items_attributes = modified_attributes
end
end
Ответ 3
Я встретил ту же проблему.
С помощью некоторых усилий я решил проблему.
Может быть, кто-то встретит тот же вопрос, поэтому я отправлю ответ здесь.
attr_writer
перезаписать оригинальный сеттер line_items
Затем вызовите super, поместите результат в настройку по умолчанию
class Order
attr_writer :line_items
has_many :line_items
def line_items=(value)
# manipulate value
# then send result to the default setter
super(result)
end