Skip to content

Commit

Permalink
Store entire options hash in the class var rather than just the rejec…
Browse files Browse the repository at this point in the history
…t_if proc for the nested attributes
  • Loading branch information
lifo committed Oct 9, 2009
1 parent 987d501 commit e94caf0
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 16 deletions.
27 changes: 15 additions & 12 deletions activerecord/lib/active_record/nested_attributes.rb
Expand Up @@ -6,8 +6,8 @@ module NestedAttributes #:nodoc:
extend ActiveSupport::Concern extend ActiveSupport::Concern


included do included do
class_inheritable_accessor :reject_new_nested_attributes_procs, :instance_writer => false class_inheritable_accessor :nested_attributes_options, :instance_writer => false
self.reject_new_nested_attributes_procs = {} self.nested_attributes_options = {}
end end


# == Nested Attributes # == Nested Attributes
Expand Down Expand Up @@ -227,18 +227,18 @@ def accepts_nested_attributes_for(*attr_names)


reflection.options[:autosave] = true reflection.options[:autosave] = true


self.reject_new_nested_attributes_procs[association_name.to_sym] = if options[:reject_if] == :all_blank self.nested_attributes_options[association_name.to_sym] = options
proc { |attributes| attributes.all? {|k,v| v.blank?} }
else if options[:reject_if] == :all_blank
options[:reject_if] self.nested_attributes_options[association_name.to_sym][:reject_if] = proc { |attributes| attributes.all? {|k,v| v.blank?} }
end 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)
# end # end
class_eval %{ class_eval %{
def #{association_name}_attributes=(attributes) def #{association_name}_attributes=(attributes)
assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes, #{options[:allow_destroy]}) assign_nested_attributes_for_#{type}_association(:#{association_name}, attributes)
end end
}, __FILE__, __LINE__ }, __FILE__, __LINE__
else else
Expand Down Expand Up @@ -282,7 +282,8 @@ def _delete #:nodoc:
# If the given attributes include a matching <tt>:id</tt> attribute _and_ a # If the given attributes include a matching <tt>:id</tt> attribute _and_ a
# <tt>:_destroy</tt> key set to a truthy value, then the existing record # <tt>:_destroy</tt> key set to a truthy value, then the existing record
# will be marked for destruction. # will be marked for destruction.
def assign_nested_attributes_for_one_to_one_association(association_name, attributes, allow_destroy) def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
options = self.nested_attributes_options[association_name]
attributes = attributes.with_indifferent_access attributes = attributes.with_indifferent_access


if attributes['id'].blank? if attributes['id'].blank?
Expand All @@ -295,7 +296,7 @@ def assign_nested_attributes_for_one_to_one_association(association_name, attrib
end end
end end
elsif (existing_record = send(association_name)) && existing_record.id.to_s == attributes['id'].to_s elsif (existing_record = send(association_name)) && existing_record.id.to_s == attributes['id'].to_s
assign_to_or_mark_for_destruction(existing_record, attributes, allow_destroy) assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
end end
end end


Expand Down Expand Up @@ -326,7 +327,9 @@ def assign_nested_attributes_for_one_to_one_association(association_name, attrib
# { :name => 'John' }, # { :name => 'John' },
# { :id => '2', :_destroy => true } # { :id => '2', :_destroy => true }
# ]) # ])
def assign_nested_attributes_for_collection_association(association_name, attributes_collection, allow_destroy) def assign_nested_attributes_for_collection_association(association_name, attributes_collection)
options = self.nested_attributes_options[association_name]

unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array) unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})" raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
end end
Expand All @@ -343,7 +346,7 @@ def assign_nested_attributes_for_collection_association(association_name, attrib
send(association_name).build(attributes.except(*UNASSIGNABLE_KEYS)) send(association_name).build(attributes.except(*UNASSIGNABLE_KEYS))
end end
elsif existing_record = send(association_name).detect { |record| record.id.to_s == attributes['id'].to_s } elsif existing_record = send(association_name).detect { |record| record.id.to_s == attributes['id'].to_s }
assign_to_or_mark_for_destruction(existing_record, attributes, allow_destroy) assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
end end
end end
end end
Expand Down Expand Up @@ -372,7 +375,7 @@ def reject_new_record?(association_name, attributes)
end end


def call_reject_if(association_name, attributes) def call_reject_if(association_name, attributes)
callback = self.class.reject_new_nested_attributes_procs[association_name] callback = self.nested_attributes_options[association_name][:reject_if]


case callback case callback
when Symbol when Symbol
Expand Down
8 changes: 4 additions & 4 deletions activerecord/test/cases/nested_attributes_test.rb
Expand Up @@ -29,13 +29,13 @@ def teardown
Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? } Pirate.accepts_nested_attributes_for :ship, :allow_destroy => true, :reject_if => proc { |attributes| attributes.empty? }
end end


def test_base_should_have_an_empty_reject_new_nested_attributes_procs def test_base_should_have_an_empty_nested_attributes_options
assert_equal Hash.new, ActiveRecord::Base.reject_new_nested_attributes_procs assert_equal Hash.new, ActiveRecord::Base.nested_attributes_options
end end


def test_should_add_a_proc_to_reject_new_nested_attributes_procs def test_should_add_a_proc_to_nested_attributes_options
[:parrots, :birds, :birds_with_reject_all_blank].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.nested_attributes_options[name][:reject_if]
end end
end end


Expand Down

0 comments on commit e94caf0

Please sign in to comment.