This project is archived and is in readonly mode.
Updating nested attributes with has_one relationship doesn't work correctly
Reported by flip | June 7th, 2009 @ 08:59 PM | in 2.x
Updating the attributes of the child model results in the creation of a new Object with nil values when using a has_one relationship and nested attributes.
>> u = User.find 1
=> #<User id: 1, login: "james", password: "secret", created_at: "2009-06-06 22:50:07", updated_at: "2009-06-06 22:50:07">
>> u.profile
=> #<Profile id: 2, user_id: 1, age: 18, city: "London", comment: "", created_at: "2009-06-06 22:51:45", updated_at: "2009-06-06 22:51:45">
>> u.attributes = {:profile_attributes => {:city => 'nowhere'}}
=> {:profile_attributes=>{:city=>"nowhere"}}
>> u.profile
=> #<Profile id: nil, user_id: 1, age: nil, city: "nowhere", comment: nil, created_at: nil, updated_at: nil>
>> u.profile.changes
=> {"city"=>[nil, "nowhere"], "user_id"=>[nil, 1]}
I've described the full scenario at
http://railsforum.com/viewtopic.php?id=31491
Comments and changes to this ticket
-
Eloy Duran June 7th, 2009 @ 09:23 PM
- State changed from new to invalid
You should include the id of the Profile to indicate it's an update you're trying to perform.
u.attributes = {:id => 2, :profile_attributes => {:city => 'nowhere'}}
For more info take a look at what the form helpers produce.
-
flip June 7th, 2009 @ 09:34 PM
ok, i guess you mean:
u.attributes = {:profile_attributes => {:id => 2, :city => 'nowhere'}}
is this documented somewhere? Using the "old way" my approach would work also without the id:
u.profile.attributes = {:city => 'nowhere'}
-
Eloy Duran June 7th, 2009 @ 09:46 PM
Oops, yeah that's what I meant :)
It's shown here: http://github.com/rails/rails/blob/master/activerecord/lib/active_r...
It is needed to differentiate between a new record or an existing one.
-
Greg June 26th, 2009 @ 12:00 AM
I'm not so sure that this should be invalid. It makes sense to need the id for has_many relationships, but for belongs_to and has_one, you should assume that they want to update the record.
In the example that flip gave, calling u.save will return no problem, and you'll end up with an orphaned profile in the database. This scenario can easily come up if you are allowing updates via REST/XML...a user can PUT
nowhereto http://<>/users/2 or wherever. The user doesn't know the ID of the nested model, but they should expect that only the city is updated in the profile, a new profile should not be created.
Unfortunately, I don't have a patch for this right now, but I believe this should be re-opened as a bug. Thanks!
-
Sébastien Luquet October 5th, 2009 @ 02:00 PM
Hi,
Documentation is about update_attributes
params = { :member' => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }
member.update_attributes params['member']What about object creation
params = { :member' => { :avatar_attributes => { :id => '2', :icon => 'sad' } } }
Member.create params['member']Does it create new Member, update Avatar with id 2 and associate the two record together ?
-
Dmitry Polushkin October 21st, 2009 @ 01:19 PM
I agree that it should be reopened. Not smart to pass id for one to one.
-
Eloy Duran October 21st, 2009 @ 01:39 PM
I'd rather see a patch that adds something like
:only_update => true' to accepts_nested_attributes_for. Or otherwise fix it in your controller if you don't trust the client.
-
Dmitry Polushkin November 1st, 2009 @ 02:33 PM
Question, how to solve:
class Team has_one :captain, :class_name => 'Player' accepts_nested_attributes_for :captain end class Player belongs_to :team validate :validate_team private def validate_team raise 'Should have team' unless team end end
Team.create!(:captain_attributes => {:name => 'Name Surname'})
Will be risen 'Should have team' because while attributes assigns to the nested model object, belongs_to associations isn't assigns.
If you know how to solve that, please tell me.
Thank you.
-
Eloy Duran December 28th, 2009 @ 11:17 PM
- State changed from invalid to resolved
Today a patch for :update_only and the ability to use :inverse_of, which fixes the last issue, have both been pushed. HTH
-
Ryan Bigg October 9th, 2010 @ 10:00 PM
- Tag cleared.
- Importance changed from to Low
Automatic cleanup of spam.
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>
People watching this ticket
Referenced by
- 3418 [PATCH]: Nested Attributes update associated record w/o passing id on one to one In #2777, Dmitry Polushkin said that passing id on one to...