提交 57232313 编写于 作者: P Pratik Naik

Allow accepts_nested_attributes_for :reject_if option accept symbols for using a method

Conflicts:

	activerecord/lib/active_record/nested_attributes.rb
上级 94159359
...@@ -127,6 +127,22 @@ module NestedAttributes #:nodoc: ...@@ -127,6 +127,22 @@ module NestedAttributes #:nodoc:
# member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!' # member.posts.first.title # => 'Kari, the awesome Ruby documentation browser!'
# member.posts.second.title # => 'The egalitarian assumption of the modern citizen' # 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 # If the hash contains an <tt>id</tt> key that matches an already
# associated record, the matching record will be modified: # associated record, the matching record will be modified:
# #
...@@ -179,10 +195,11 @@ module ClassMethods ...@@ -179,10 +195,11 @@ module ClassMethods
# <tt>_destroy</tt> key and a value that evaluates to +true+ # <tt>_destroy</tt> key and a value that evaluates to +true+
# (eg. 1, '1', true, or 'true'). This option is off by default. # (eg. 1, '1', true, or 'true'). This option is off by default.
# [:reject_if] # [:reject_if]
# Allows you to specify a Proc that checks whether a record should be # Allows you to specify a Proc or a Symbol pointing to a method
# built for a certain attribute hash. The hash is passed to the Proc # that checks whether a record should be built for a certain attribute
# and the Proc should return either +true+ or +false+. When no Proc # hash. The hash is passed to the supplied Proc or the method
# is specified a record will be built for all attribute hashes that # 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. # 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 # Passing <tt>:all_blank</tt> instead of a Proc will create a proc
# that will reject a record where all the attributes are blank. # that will reject a record where all the attributes are blank.
...@@ -351,8 +368,18 @@ def has_destroy_flag?(hash) ...@@ -351,8 +368,18 @@ def has_destroy_flag?(hash)
# has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this # has_destroy_flag? or if a <tt>:reject_if</tt> proc exists for this
# association and evaluates to +true+. # association and evaluates to +true+.
def reject_new_record?(association_name, attributes) def reject_new_record?(association_name, attributes)
has_destroy_flag?(attributes) || has_destroy_flag?(attributes) || call_reject_if(association_name, attributes)
self.class.reject_new_nested_attributes_procs[association_name].try(:call, 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 end
end end
...@@ -84,6 +84,26 @@ def test_underscore_delete_is_deprecated ...@@ -84,6 +84,26 @@ def test_underscore_delete_is_deprecated
ship = Ship.create!(:name => 'Nights Dirty Lightning') ship = Ship.create!(:name => 'Nights Dirty Lightning')
ship._delete ship._delete
end 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 end
class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase class TestNestedAttributesOnAHasOneAssociation < ActiveRecord::TestCase
......
...@@ -45,6 +45,10 @@ def ship_log ...@@ -45,6 +45,10 @@ def ship_log
@ship_log ||= [] @ship_log ||= []
end end
def reject_empty_ships_on_create(attributes)
attributes.delete('_reject_me_if_new').present? && new_record?
end
private private
def log_before_add(record) def log_before_add(record)
log(record, "before_adding_method") log(record, "before_adding_method")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册