Permalink
Browse files

Allow accepts_nested_attributes_for :reject_if option accept symbols …

…for using a method

Conflicts:

	activerecord/lib/active_record/nested_attributes.rb
  • Loading branch information...
1 parent 9415935 commit 572323135f235cc43e8a5bbafa3a634b4ec71ba8 @lifo lifo committed Oct 7, 2009
@@ -127,6 +127,22 @@ module NestedAttributes #:nodoc:
# member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
# member.posts.second.title # => 'The egalitarian assumption of the modern citizen'
#
+ # Alternatively, :reject_if also accepts a symbol for using methods:
+ #
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :new_record?
+ # end
+ #
+ # class Member < ActiveRecord::Base
+ # has_many :posts
+ # accepts_nested_attributes_for :posts, :reject_if => :reject_posts
+ #
+ # def reject_posts(attributed)
+ # attributed['title].blank?
+ # end
+ # end
+ #
# If the hash contains an <tt>id</tt> key that matches an already
# associated record, the matching record will be modified:
#
@@ -179,10 +195,11 @@ module ClassMethods
# <tt>_destroy</tt> key and a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'). This option is off by default.
# [:reject_if]
- # Allows you to specify a Proc that checks whether a record should be
- # built for a certain attribute hash. The hash is passed to the 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
+ # Allows you to specify a Proc or a Symbol pointing to a method
+ # that checks whether a record should be built for a certain attribute
+ # hash. The hash is passed to the supplied Proc or the method
+ # and it should return either +true+ or +false+. When no :reject_if
+ # is specified, a record will be built for all attribute hashes that
# do not have a <tt>_destroy</tt> value 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.
@@ -351,8 +368,18 @@ def has_destroy_flag?(hash)
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
# association and evaluates to +true+.
def reject_new_record?(association_name, attributes)
- has_destroy_flag?(attributes) ||
- self.class.reject_new_nested_attributes_procs[association_name].try(:call, attributes)
+ has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
+ end
+
+ def call_reject_if(association_name, attributes)
+ callback = self.class.reject_new_nested_attributes_procs[association_name]
+
+ case callback
+ when Symbol
+ method(callback).arity == 0 ? send(callback) : send(callback, attributes)
+ when Proc
+ callback.try(:call, attributes)
+ end
end
end
end
@@ -84,6 +84,26 @@ def test_underscore_delete_is_deprecated
ship = Ship.create!(:name => 'Nights Dirty Lightning')
ship._delete
end
+
+ def test_reject_if_method_without_arguments
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => :new_record?
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :name => 'Black Pearl' }
+ assert_no_difference('Ship.count') { pirate.save! }
+ end
+
+ def test_reject_if_method_with_arguments
+ Pirate.accepts_nested_attributes_for :ship, :reject_if => :reject_empty_ships_on_create
+
+ pirate = Pirate.new(:catchphrase => "Stop wastin' me time")
+ pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
+ assert_no_difference('Ship.count') { pirate.save! }
+
+ # pirate.reject_empty_ships_on_create returns false for saved records
+ pirate.ship_attributes = { :name => 'Red Pearl', :_reject_me_if_new => true }
+ assert_difference('Ship.count') { pirate.save! }
+ end
end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
@@ -45,6 +45,10 @@ def ship_log
@ship_log ||= []
end
+ def reject_empty_ships_on_create(attributes)
+ attributes.delete('_reject_me_if_new').present? && new_record?
+ end
+
private
def log_before_add(record)
log(record, "before_adding_method")

0 comments on commit 5723231

Please sign in to comment.