Reputation: 14458
I gave on trying to override the autosave
parameter since I think it can't be done.
I moved the has_shipping_address
from the Order
to the ShippingAddress
model and now I have:
#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 %>
The problem is that :reject_if
doesn't seem to do it's job. No matter what the value for has_shipping_address
is, the save
method is still called on the nested ShippingAddress
, resulting in validation errors.
Am I doing something wrong here? This is getting a bit frustrating.
Upvotes: 5
Views: 5457
Reputation: 14458
Turns out the :reject_if
didn't work because I was doing the building of the nested shipping_address
in the after_initialize
callback of the order.
After moving that to view (or a helper method), it works as expected.
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 %>
I hope at least this will help someone else too, as it has been very frustrating for me to figure out.
Upvotes: 10