diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb index 5290113fe0067..16c95f9e42dfa 100644 --- a/activerecord/lib/active_record/nested_attributes.rb +++ b/activerecord/lib/active_record/nested_attributes.rb @@ -217,6 +217,8 @@ module ClassMethods # Examples: # # creates avatar_attributes= # accepts_nested_attributes_for :avatar, :reject_if => proc { |attributes| attributes['name'].blank? } + # # creates avatar_attributes= + # accepts_nested_attributes_for :avatar, :reject_if => :all_blank # # creates avatar_attributes= and posts_attributes= # accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true def accepts_nested_attributes_for(*attr_names) @@ -236,6 +238,10 @@ def accepts_nested_attributes_for(*attr_names) reflection.options[:autosave] = true add_autosave_association_callbacks(reflection) self.nested_attributes_options[association_name.to_sym] = options + + if options[:reject_if] == :all_blank + self.nested_attributes_options[association_name.to_sym][:reject_if] = proc { |attributes| attributes.all? {|k,v| v.blank?} } + end # def pirate_attributes=(attributes) # assign_nested_attributes_for_one_to_one_association(:pirate, attributes) diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb index b26ba841a854e..e0637ca11d4d9 100644 --- a/activerecord/test/cases/nested_attributes_test.rb +++ b/activerecord/test/cases/nested_attributes_test.rb @@ -33,11 +33,27 @@ def test_base_should_have_an_empty_nested_attributes_options end def test_should_add_a_proc_to_nested_attributes_options - [:parrots, :birds].each do |name| + [:parrots, :birds, :birds_with_reject_all_blank].each do |name| assert_instance_of Proc, Pirate.nested_attributes_options[name][:reject_if] end end + def test_should_not_build_a_new_record_if_reject_all_blank_returns_false + pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{:name => '', :color => ''}] + pirate.save! + + assert pirate.birds_with_reject_all_blank.empty? + end + + def test_should_build_a_new_record_if_reject_all_blank_does_not_return_false + pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?") + pirate.birds_with_reject_all_blank_attributes = [{:name => 'Tweetie', :color => ''}] + pirate.save! + + assert_equal 1, pirate.birds_with_reject_all_blank.count + end + def test_should_raise_an_ArgumentError_for_non_existing_associations assert_raise_with_message ArgumentError, "No association found for name `honesty'. Has it been defined yet?" do Pirate.accepts_nested_attributes_for :honesty diff --git a/activerecord/test/models/pirate.rb b/activerecord/test/models/pirate.rb index 86ad12165adcb..88c163471770c 100644 --- a/activerecord/test/models/pirate.rb +++ b/activerecord/test/models/pirate.rb @@ -32,12 +32,14 @@ class Pirate < ActiveRecord::Base :after_add => proc {|p,b| p.ship_log << "after_adding_proc_bird_#{b.id || ''}"}, :before_remove => proc {|p,b| p.ship_log << "before_removing_proc_bird_#{b.id}"}, :after_remove => proc {|p,b| p.ship_log << "after_removing_proc_bird_#{b.id}"} + has_many :birds_with_reject_all_blank, :class_name => "Bird" accepts_nested_attributes_for :parrots, :birds, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } accepts_nested_attributes_for :update_only_ship, :update_only => true accepts_nested_attributes_for :parrots_with_method_callbacks, :parrots_with_proc_callbacks, :birds_with_method_callbacks, :birds_with_proc_callbacks, :allow_destroy => true + accepts_nested_attributes_for :birds_with_reject_all_blank, :reject_if => :all_blank validates_presence_of :catchphrase diff --git a/activerecord/test/schema/schema.rb b/activerecord/test/schema/schema.rb index dcb53a7a292a5..9ca07c79c3c28 100644 --- a/activerecord/test/schema/schema.rb +++ b/activerecord/test/schema/schema.rb @@ -58,6 +58,7 @@ def create_table(*args, &block) create_table :birds, :force => true do |t| t.string :name + t.string :color t.integer :pirate_id end