Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails accepts_nested_attributes_for :reject_if not working

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.

like image 879
andi Avatar asked Jun 24 '09 10:06

andi


1 Answers

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.

like image 92
andi Avatar answered Sep 16 '22 13:09

andi