提交 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:
# 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")
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册