rails accepts_nested_attributes_for: reject_if не работает
-
10-07-2019 - |
Вопрос
Я попытался переопределить параметр autosave
, поскольку думаю, что это невозможно.
Я переместил has_shipping_address
из Order
в модель ShippingAddress
, и теперь у меня есть:
#the models..
class Order < ActiveRecord::Base
belongs_to :billing_address
belongs_to :shipping_address
accepts_nested_attributes_for :billing_address
accepts_nested_attributes_for :shipping_address, :reject_if => proc { |attributes| attributes["has_shipping_address"] != '1' }
def after_initialize
self.build_billing_address unless billing_address
self.build_shipping_address unless shipping_address
end
end
class ShippingAddress < OrderAddress
attr_accessor :has_shipping_address
end
class OrderAddress < ActiveRecord::Base
validates_presence_of :name
#more validations here..
end
#the view
<% form_for @order do |f| %>
#...
<% f.fields_for :shipping_address do |addr_f| %>
<%= addr_f.check_box :has_shipping_address %>
<%= addr_f.text_field :name %>
#more fields for the address..
<% end %>
<% end %>
Проблема в том, что : reject_if
, похоже, не выполняет свою работу. Независимо от значения has_shipping_address
, метод save
все еще вызывается для вложенного ShippingAddress
, что приводит к ошибкам проверки.
Я что-то здесь не так делаю? Это немного расстраивает.
Решение
Оказывается, : reject_if
не работает, потому что я делал создание вложенного shipping_address
в обратном вызове after_initialize
заказа ,
После перемещения этого в представление (или вспомогательный метод) он работает как положено.
def after_initialize
self.build_billing_address unless billing_address
end
#the view is now
<% form_for @order do |f| %>
#...
<% @order.build_shipping_address unless @order.shipping_address %>
<% f.fields_for :shipping_address do |addr_f| %>
<%= addr_f.check_box :has_shipping_address %>
<%= addr_f.text_field :name %>
#more fields for the address..
<% end %>
<% end %>
Надеюсь, по крайней мере, это поможет кому-то еще, так как мне было очень сложно разобраться.