This project is archived and is in readonly mode.
Assigning nested attributes fails for new object when ID is specified
Reported by Tyler Gannon | March 22nd, 2010 @ 10:13 PM
I see Alloy's name a lot in the recent history for nested_attributes.rb so he might be the best to implement this fix.
Steps to recreate:
for example:
class Person < ActiveRecord::Base
has_many :arms accepts_nested_attributes_for :arms end
now in the console:
Arm.create(:length => "3in") Person.new( { "arms_attributes" => {"0" => { "id" => Arm.last.id.to_s } } } )
Expected:
new Person object with the recently created Arm object added to the
arms collection.
Actual:
ActiveRecord::RecordNotFound: Couldn't find Arm with ID=1 for
Person with ID=
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/nested_attributes.rb:395:in `raise_nested_attributes_record_not_found'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/nested_attributes.rb:357:in `assign_nested_attributes_for_collection_association'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/nested_attributes.rb:347:in `each'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/nested_attributes.rb:347:in `assign_nested_attributes_for_collection_association'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/nested_attributes.rb:252:in `arms_attributes='
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:1988:in `send'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:1988:in `attributes='
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:1984:in `each'
from /usr/lib/ruby/gems/1.8/gems/activerecord-3.0.0.beta/lib/active_record/base.rb:1984:in `attributes='
from (irb):12
Take a look at that area in nested_attributes.rb:354 and it is expecting that the nested attribute collection should already contain a member with the same id as the one being added, otherwise it will raise an exception. This implies an assumption that if the child object is going to be mentioned in the attributes hash, then it should either be a new object or it should already belong to the parent. This creates a problem for anyone trying to build a new parent object using the ids of the child objects.
Or am I missing something important in the usage here?
Comments and changes to this ticket
-
David Trasbo April 15th, 2010 @ 11:51 AM
- Assigned user set to Ryan Bigg
Tyler,
In this case you should use
arm_ids
:Person.new(:arm_ids => [1, 2, 3])
This ticket can be marked as invalid.
-
Ryan Bigg April 15th, 2010 @ 11:52 AM
- State changed from new to invalid
-
Dave Myron January 10th, 2011 @ 01:03 AM
- Importance changed from to Low
I'd like to reopen discussion on this. Consider a three-level nested attribute setup: Something like Subscription -> User -> Credit Card (each accepting nested attributes of the parent) and in the Subscription form you have the Subscription, User and Credit Card fields.
If the User exists but doesn't have a Credit Card yet, then this error is thrown when trying to create a Subscription with an existing user and trying to provide Credit Card details. Imagine the Subscription form having a dropdown of existing users which would set
subscription[user_attributes][id]
and then specifyingsubscription[user_attributes][credit_card_attributes]
values.The resulting params would look something like
{:subscription => {:user_attributes => {:id => 1, :credit_card_attributes => { ... }}}
I'd expect that work (as did the original reporter).
Can you suggest an existing way to accomplish this? (You wouldn't be able to use nested attributes, I'm guessing, and instead have to look for a separate credit_card param and shim it in.)
-
Dave Myron January 10th, 2011 @ 07:33 AM
In
assign_nested_attributes_for_one_to_one_association
maybe it ought to look at thepersisted?
state and, if not persisted, reflect on the association and use the itsfind
with theid
given in the attributes.I'm curious if CVE-2010-3933 (Rails v3.0.1) is related to this.
-
Dave Myron January 10th, 2011 @ 07:37 AM
Hmm... looks like my suggestion above is exactly what was removed in Rails v3.0.1 because of CVE-2010-3933. That's a bummer.
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>