Accepts_nested_attributes_for :reject_if issue

I have the following 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

And 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 missing something here?
Thanks.

Andrei Don wrote:

I have the following 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

And 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 missing something here?
Thanks.

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 %>