This project is archived and is in readonly mode.
Nested attributes are saved twice
Reported by gix | November 30th, 2009 @ 09:56 PM | in 2.3.6
Nested attributes are saved twice. Suppose a definition like this, each having a name column:
class Person < ActiveRecord::Base
has_many :children
accepts_nested_attributes_for :children
end
class Child < ActiveRecord::Base
belongs_to :person
before_save do
puts "before save"
end
end
Creating a person with nested attributes reveils that the child is saved twice (i.e. insert+update, or update+update):
>> Person.create(:name=>'Person',:children_attributes=>[{:name=>'Child'}])
before save!
before save!
=> #<Person id: 1, name: "Person", child_id: nil, created_at: "2009-11-30 21:26:44", updated_at: "2009-11-30 21:26:44">
This usually won't result in two queries though, since the dirty-feature removes all updated columns after the first save:
SQL (0.1ms) BEGIN
Person Create (0.4ms) INSERT INTO `people` (`name`, `created_at`, `updated_at`, `child_id`) VALUES('Person', '2009-11-30 21:27:15', '2009-11-30 21:27:15', NULL)
Child Create (0.2ms) INSERT INTO `children` (`name`, `created_at`, `updated_at`) VALUES('Child', '2009-11-30 21:27:15', '2009-11-30 21:27:15')
SQL (1.3ms) COMMIT
The reason for this is that
AutosaveAssociation#save_collection_association
is set
up twice as an after-callback for create and update: first when
calling has_many :children
(AutosaveAssociation
overwrites has_many
et al and adds a call to
add_autosave_association_callbacks
), and second when
calling accepts_nested_attributes_for
(calls
add_autosave_association_callbacks
right after
defining the nested attributes setter). So in turn the save method
is overwritten with an equivalent one, and added again as a
callback.
I'm not sure what would be the best way to fix this (or whether
this is actually intended behavior). The call to
add_autosave_association_callbacks
should probably be
dropped from accepts_nested_attributes_for
since it
requires an association anyway. Otherwise a simple
return if method_defined? save_method
at the top of
add_autosave_association_callbacks
works, but only
cures the symptom.
Comments and changes to this ticket
-
Cyrille December 15th, 2009 @ 05:30 PM
I confirm the exact same problem on 2.3.5 however the exact same code 2.3.4 works
-
Eloy Duran December 30th, 2009 @ 07:37 PM
- Assigned user set to Eloy Duran
-
Eloy Duran December 30th, 2009 @ 07:37 PM
- Milestone set to 2.3.6
-
Eloy Duran January 8th, 2010 @ 11:07 AM
- State changed from new to resolved
This has recently been fixed on 2-3-stable and master. For instance: http://github.com/rails/rails/commit/146a7505680cbb646c0b9d55dca7cc...
Thanks!
-
goodwill January 13th, 2010 @ 09:30 AM
How can I get that applied immediately? I stuck on this already :(
-
Eloy Duran January 13th, 2010 @ 09:46 AM
@goodwill You'll have to use ‘edge’ rails. If this is a 2.3.x app, you could simply do a checkout of the repo and 2-3-stable branch in ./vendor/rails. If you're on master see this: http://yehudakatz.com/2009/12/31/spinning-up-a-new-rails-app
Any more questions should go to the rubyonrails-talk mailing list: http://groups.google.com/group/rubyonrails-talk
Create your profile
Help contribute to this project by taking a few moments to create your personal profile. Create your profile »
<h2 style="font-size: 14px">Tickets have moved to Github</h2>
The new ticket tracker is available at <a href="https://github.com/rails/rails/issues">https://github.com/rails/rails/issues</a>