aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/nested_attributes.rb
diff options
context:
space:
mode:
authorEloy Duran <eloy.de.enige@gmail.com>2009-12-28 21:08:20 +0100
committerEloy Duran <eloy.de.enige@gmail.com>2009-12-28 21:09:22 +0100
commitc23fbd0d475612fe9cd493bd08c8da2f8d7e6f03 (patch)
treeec206751fb4743393bbbf603c38dbdcd3fb405a2 /activerecord/lib/active_record/nested_attributes.rb
parent07b615fb897017d7acfaafa88606bc88be30f6e4 (diff)
downloadrails-c23fbd0d475612fe9cd493bd08c8da2f8d7e6f03.tar.gz
rails-c23fbd0d475612fe9cd493bd08c8da2f8d7e6f03.tar.bz2
rails-c23fbd0d475612fe9cd493bd08c8da2f8d7e6f03.zip
Refactored previous changes to nested attributes.
Diffstat (limited to 'activerecord/lib/active_record/nested_attributes.rb')
-rw-r--r--activerecord/lib/active_record/nested_attributes.rb50
1 files changed, 18 insertions, 32 deletions
diff --git a/activerecord/lib/active_record/nested_attributes.rb b/activerecord/lib/active_record/nested_attributes.rb
index 5143e804d1..ff3a51d5c0 100644
--- a/activerecord/lib/active_record/nested_attributes.rb
+++ b/activerecord/lib/active_record/nested_attributes.rb
@@ -213,9 +213,9 @@ module ActiveRecord
# exception is raised. If omitted, any number associations can be processed.
# Note that the :limit option is only applicable to one-to-many associations.
# [:update_only]
- # Allows to specify that the an existing record can only be updated.
- # A new record in only created when there is no existing record. This
- # option only works for on-to-one associations and is ignored for
+ # Allows you to specify that an existing record may only be updated.
+ # A new record may only be created when there is no existing record.
+ # This option only works for one-to-one associations and is ignored for
# collection associations. This option is off by default.
#
# Examples:
@@ -248,7 +248,7 @@ module ActiveRecord
end
# 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)
# end
class_eval %{
def #{association_name}_attributes=(attributes)
@@ -289,43 +289,29 @@ module ActiveRecord
# Assigns the given attributes to the association.
#
- # If the given attributes include an <tt>:id</tt> that matches the existing
- # record’s id, then the existing record will be modified. Otherwise a new
- # record will be built.
- #
- # If update_only is true, a new record is only created when no object exists,
- # otherwise it will be updated
- #
# If update_only is false and the given attributes include an <tt>:id</tt>
# that matches the existing record’s id, then the existing record will be
- # modified. Otherwise a new record will be built.
+ # modified. If update_only is true, a new record is only created when no
+ # object exists. Otherwise a new record will be built.
#
- # 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
- # will be marked for destruction.
+ # If the given attributes include a matching <tt>:id</tt> attribute, or
+ # update_only is true, and a <tt>:_destroy</tt> key set to a truthy value,
+ # then the existing record will be marked for destruction.
def assign_nested_attributes_for_one_to_one_association(association_name, attributes)
options = self.nested_attributes_options[association_name]
attributes = attributes.with_indifferent_access
+ check_existing_record = (options[:update_only] || !attributes['id'].blank?)
- if options[:update_only]
- if existing_record = send(association_name)
- assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
+ if check_existing_record && (record = send(association_name)) &&
+ (options[:update_only] || record.id.to_s == attributes['id'].to_s)
+ assign_to_or_mark_for_destruction(record, attributes, options[:allow_destroy])
+ elsif !reject_new_record?(association_name, attributes)
+ method = "build_#{association_name}"
+ if respond_to?(method)
+ send(method, attributes.except(*UNASSIGNABLE_KEYS))
else
- unless reject_new_record?(association_name, attributes)
- send("build_#{association_name}", attributes.except(*UNASSIGNABLE_KEYS))
- end
- end
- elsif attributes['id'].blank?
- unless reject_new_record?(association_name, attributes)
- method = "build_#{association_name}"
- if respond_to?(method)
- send(method, attributes.except(*UNASSIGNABLE_KEYS))
- else
- raise ArgumentError, "Cannot build association #{association_name}. Are you trying to build a polymorphic one-to-one association?"
- end
+ raise ArgumentError, "Cannot build association #{association_name}. Are you trying to build a polymorphic one-to-one association?"
end
- elsif (existing_record = send(association_name)) && existing_record.id.to_s == attributes['id'].to_s
- assign_to_or_mark_for_destruction(existing_record, attributes, options[:allow_destroy])
end
end