1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Allow you to pass :all_blank to :reject_if option to automatically create a Proc that will reject any record with blank attributes.

This commit is contained in:
Mike Breen 2009-05-10 15:02:00 +12:00 committed by Michael Koziarski
parent 026b78f907
commit 9010ed2755
4 changed files with 30 additions and 2 deletions

View file

@ -180,10 +180,14 @@ module ActiveRecord
# and the Proc should return either +true+ or +false+. When no Proc # and the Proc should return either +true+ or +false+. When no Proc
# is specified a record will be built for all attribute hashes that # is specified a record will be built for all attribute hashes that
# do not have a <tt>_delete</tt> that evaluates to true. # do not have a <tt>_delete</tt> that evaluates to true.
# Passing <tt>:all_blank</tt> instead of a Proc will create a proc
# that will reject a record where all the attributes are blank.
# #
# Examples: # Examples:
# # creates avatar_attributes= # # creates avatar_attributes=
# accepts_nested_attributes_for :avatar, :reject_if => proc { |attributes| attributes['name'].blank? } # 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= # # creates avatar_attributes= and posts_attributes=
# accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true # accepts_nested_attributes_for :avatar, :posts, :allow_destroy => true
def accepts_nested_attributes_for(*attr_names) def accepts_nested_attributes_for(*attr_names)
@ -201,7 +205,12 @@ module ActiveRecord
end end
reflection.options[:autosave] = true reflection.options[:autosave] = true
self.reject_new_nested_attributes_procs[association_name.to_sym] = options[:reject_if]
self.reject_new_nested_attributes_procs[association_name.to_sym] = if options[:reject_if] == :all_blank
proc { |attributes| attributes.all? {|k,v| v.blank?} }
else
options[:reject_if]
end
# def pirate_attributes=(attributes) # def pirate_attributes=(attributes)
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes, false) # assign_nested_attributes_for_one_to_one_association(:pirate, attributes, false)

View file

@ -31,11 +31,27 @@ class TestNestedAttributesInGeneral < ActiveRecord::TestCase
end end
def test_should_add_a_proc_to_reject_new_nested_attributes_procs def test_should_add_a_proc_to_reject_new_nested_attributes_procs
[:parrots, :birds].each do |name| [:parrots, :birds, :birds_with_reject_all_blank].each do |name|
assert_instance_of Proc, Pirate.reject_new_nested_attributes_procs[name] assert_instance_of Proc, Pirate.reject_new_nested_attributes_procs[name]
end end
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 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 assert_raise_with_message ArgumentError, "No association found for name `honesty'. Has it been defined yet?" do
Pirate.accepts_nested_attributes_for :honesty Pirate.accepts_nested_attributes_for :honesty

View file

@ -28,11 +28,13 @@ class Pirate < ActiveRecord::Base
:after_add => proc {|p,b| p.ship_log << "after_adding_proc_bird_#{b.id || '<new>'}"}, :after_add => proc {|p,b| p.ship_log << "after_adding_proc_bird_#{b.id || '<new>'}"},
:before_remove => proc {|p,b| p.ship_log << "before_removing_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}"} :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 :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 :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
accepts_nested_attributes_for :parrots_with_method_callbacks, :parrots_with_proc_callbacks, accepts_nested_attributes_for :parrots_with_method_callbacks, :parrots_with_proc_callbacks,
:birds_with_method_callbacks, :birds_with_proc_callbacks, :allow_destroy => true :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 validates_presence_of :catchphrase

View file

@ -57,6 +57,7 @@ ActiveRecord::Schema.define do
create_table :birds, :force => true do |t| create_table :birds, :force => true do |t|
t.string :name t.string :name
t.string :color
t.integer :pirate_id t.integer :pirate_id
end end