Fwd: Problem using nested_attributes for habtm relationship

Chirag Viradiya
Tue, 03 May 2011 09:07:32 -0000

---------- Forwarded message ----------
From: Chirag Viradiya <chirag_viradiya@persistent.co.in>
Date: Tue, May 3, 2011 at 2:20 PM
Subject: Problem using nested_attributes for habtm relationship
To: aaron.patterson@gmail.com, jose.valim@plataformatec.com.br,
david@loudthinking.com
Cc: rubyonrails-core@googlegroups.com, Surbhi Gupta <
surbhi_gupta@persistent.co.in>, chirag.viradiya@gmail.com,
saroo2603@gmail.com


Hi,



We are trying to use nested attributes for habtm relationship. While doing
the same we are facing some issues with the current implementation of *
nested_attributes.rb* file in active_record.





*Problem statement: *

* *

Assign roles to user using nested attributes; user and roles are connected
through habtm.



Rails version: 2.3.8

* *

* *

>> @user = User.find(1);params = { :roles_attributes => { "0"
=> {:id => 1}}
};@user.update_attributes(params)



ActiveRecord::RecordNotFound: Couldn''t find Role with ID=1 for User
with
ID=1

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:412:in
`raise_nested_attributes_record_not_found''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:374:in
`assign_nested_attributes_for_collection_association''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:354:in
`each''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:354:in
`assign_nested_attributes_for_collection_association''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/nested_attributes.rb:244:in
`roles_attributes=''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2906:in
`send''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2906:in
`assign_attributes''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2902:in
`each''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2902:in
`assign_attributes''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2775:in
`attributes=''

        from
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.8/lib/active_record/base.rb:2663:in
`update_attributes''

        from (irb):1



*Investigation:*

After investigating on this error, we found that active_record
(nested_attributes.rb) doesn’t have any provision to update the bridge table
for an already existing associated record. To solve this we tried following
minor fix –



--- \lib\ruby\gems\1.8\gems\activerecord-2.3.8\lib\active_record
\nested_attributes.rb              Tue May 03 12:59:16 2011

+++ \lib\ruby\gems\1.8\gems\activerecord-2.3.8\lib\active_record \
nested_attributes_modified.rb     Tue May 03 13:00:05 2011

@@ -362,7 +362,7 @@

           association.send(:add_record_to_target_with_callbacks,
existing_record) unless association.loaded?

           assign_to_or_mark_for_destruction(existing_record, attributes,
options[:allow_destroy])

         else

-          raise_nested_attributes_record_not_found(association_name,
attributes[''id''])

+          association.send("<<",
association_name.to_s.capitalize.singularize.constantize.find(attributes[''id'']))

         end

       end

     end



This fix adds the record to the bridge table on executing the above command
on the console. *Please review the fix and let us know if this is the
appropriate solution to the problem.*



*Impact on other relationships:*

* *

*has_many*

* *

**

* *

This fix when executed as “@user = User.find(1);params = { :books_attributes
=> { "0" => {:id => 1}} };@user.update_attributes(params)”
gives following
results

·         If *no* book exist with the id provided in book_attributes hash–
It raises active record exception saying “No Book found with ID=1”

·         If book exists with the id provided in book_attributes hash – It
updates the “user_id” in the book table as “1” (the ID of the calling user)

* *

*has_many,  :through*

* *

**

* *

This fix when executed as “@user = User.find(1);params = {
:articles_attributes => { "0" => {:id =>7}}
};@user.update_attributes(params)” gives following results

·         If *no* article exist with the id provided in articles _attributes
hash– It raises active record exception saying “No Article found with ID=7”

·         If article exists with the id provided in articles _attributes
hash – It updates the “user_id” and “article_id” in the through(readings)
table.

* *

*has_one:*

* *

Similar behavior.

* *

Thanks and Regards,

Chirag Viradiya and Surbhi Gupta

* *

* *

* *













DISCLAIMER ========== This e-mail may contain privileged and confidential
information which is the property of Persistent Systems Ltd. It is intended
only for the use of the individual or entity to which it is addressed. If
you are not the intended recipient, you are not authorized to read, retain,
copy, print, distribute or use this message. If you have received this
communication in error, please notify the sender and delete all copies of
this message. Persistent Systems Ltd. does not accept any liability for
virus infected mails.