This project is archived and is in readonly mode.
attr_accessor not accessible through accepts_nested_attributes_for
Reported by Chris Anderson | November 9th, 2010 @ 07:17 PM | in 3.x
I'm on rails v2.3.9 and I'm seeing strange behaviour (to me anyways) in accepts_nested_attributes_for. In a certain circumstance the attr_accessor is not available on the nested model.
Tracker
has_many :samples
accepts_nested_attributes_for :samples, :allow_destroy => true
Sample
attr_accessor :current_user
belongs_to :tracker
after_destroy do |sample|
puts sample.current_user
end
On the console...
>>t = Tracker.first
>>tracker_attributes = {:note=>"a note",:samples_attributes=>{"1"=>{:sample_note=>"new sample", :current_user=>"console user", :_destroy=>false}}}
>>t.update_attributes(tracker_attributes)
=> '' # no output because _destroy is set to false
>>tracker_attributes = {:note=>"a note",:samples_attributes=>{"1"=>{:id=>1, :sample_note=>"new sample", :current_user=>"console user", :_destroy=>true}}
>>t.update_attributes(tracker_attributes)
=> 'console user'
In the above example everything works as expected and the sample is deleted. If I reload the Tracker after the Sample is created then current_user is not available.
>>t = Tracker.first
>>tracker_attributes = {:note=>"a note",:samples_attributes=>{"1"=>{:sample_note=>"new sample", :current_user=>"console user", :_destroy=>false}}}
>>t.update_attributes(tracker_attributes)
=> 'console user'
>>t = Tracker.first
>>tracker_attributes = {:note=>"a note",:samples_attributes=>{"1"=>{:id=>1, :sample_note=>"new sample", :current_user=>"console user", :_destroy=>true}}
>>t.update_attributes(tracker_attributes)
=> '' # console_user is expected but nil was printed
I'm reloading the Tracker to simulate what I see in a controller. In a controller action I would find the Tracker and then update the attributes. I hope I'm making sense.
Comments and changes to this ticket
-
Neeraj Singh November 10th, 2010 @ 03:08 PM
- Importance changed from to Low
I followed what you have shown in console. I am still not sure what is the issue? Can you elaborate on what you mean by "the attr_accessor is not available on the nested model." ?
-
Chris Anderson November 10th, 2010 @ 03:36 PM
Sure. When "accepts_nested_attributes_for :allow_destroy => true" is set, if I set the :_destroy field of a nested model record in my form to true then it will delete the child records associated with the model. This works as expected and the destroy callbacks are called.
In that same form if I set a field that's also an attr_accessor for the nested model, in this case :current_user, :current_user is not available in the destroy callbacks. It is available in the other callbacks, however.
Basically, I'm trying to use :current_user for an audit log to track who did what and when I delete child records in this fashion :current_user is not available to put the person's name into the log.
In the examples above I've tried to show that it will work if the parent record is not reloaded, but if it is (like when a form is submitted you fetch the parent record again) then it fails to retain the attr_accessor so it can be called in a destroy callback.
-
Neeraj Singh November 10th, 2010 @ 04:22 PM
@cpanderson thanks for the quick reply.
I updated the original ticket to better reflect the expected vs actual values. Can you confirm that my editing rightly reflects your issue.
Thankss
-
Chris Anderson November 10th, 2010 @ 04:29 PM
Thanks, Neeraj.
Basically, that would work except that :current_user won't be outputted in the first case because :_destroy => false. And in the second case it doesn't seem to return nil...it returns nothing at all, like it's being ignored entirely.
-
Chris Anderson November 10th, 2010 @ 04:44 PM
If I manually add a virtual attribute via getter and setter methods instead of using attr_accessor like this...
def current_user=(user) @current_user = user end def current_user @current_user || "this was not set" end
...then it will return "this was not set". In all other cases (save, update) the @current_user is returned properly.
PS. How do I add syntax highlighting like I see in other posts for ruby?
-
Neeraj Singh November 10th, 2010 @ 08:34 PM
- State changed from new to open
- Milestone set to 2.x
- Tag set to 2.3.x, patched
- Assigned user set to José Valim
Attached is a code fix with test.
Thanks a ton to Chris for helping me understand the issue.
I will investigate if it is an issue with Rails3 too?
-
Chris Anderson November 10th, 2010 @ 08:38 PM
I haven't migrated to v3 yet so I'll leave that up to you guys.
This is my first foray into submitting a bug for rails. You have attached a patch. What's the best way to handle it?
Thanks!
Chris
-
Neeraj Singh November 10th, 2010 @ 08:54 PM
@Chrirs First of all thanks for submitting the issue.
As you can see I have assigned the ticket to José Valim. He will take a look at the attached patch and will provide feedback when he gets time.
-
Neeraj Singh November 11th, 2010 @ 03:53 PM
This issue is present in Rails 3 too.
If the patch looks okay then I can create a patch for Rails 3 too?
-
Neeraj Singh November 16th, 2010 @ 06:52 PM
- Milestone changed from 2.x to 3.x
-
Repository November 24th, 2010 @ 09:09 PM
- State changed from open to resolved
(from [66212f69acc3d51af10ff76a18ff4c0bfa305ea5]) If a nested_attribute is being marked for destruction and at the same time an attr_accessor value is being assigned then the value being assigned is being ignored. This patch is a fix for that issue.
[#5939 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
https://github.com/rails/rails/commit/66212f69acc3d51af10ff76a18ff4... -
Repository November 24th, 2010 @ 09:10 PM
(from [1e2981fa6bd67089e4cae35d40fd1044f29cb6a6]) If a nested_attribute is being marked for destruction and at the same time an attr_accessor value is being assigned then the value being assigned is being ignored. This patch is a fix for that issue.
[#5939 state:resolved]
Signed-off-by: José Valim jose.valim@gmail.com
https://github.com/rails/rails/commit/1e2981fa6bd67089e4cae35d40fd1... -
Aaron Patterson December 1st, 2010 @ 01:56 AM
@Neeraj The patch that you wrote is causing warnings on master. Can you possibly rewrite this test to not use global variables?
-
joson April 29th, 2011 @ 09:13 AM
A Replica Breitling is a timepiece of high quality and functionality and you will have all the class, prestige and luxury of a wealthy, successful individual. By choosing from our selection of luxury Replica Watches , you can improve your self-esteem and feel confident to enter new circles of business associates and friends. These Rolex Replicas will surely enhance your style and only you will know the watch you wear did not cost you $1,000's of dollars.
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
Attachments
Referenced by
- 5939 attr_accessor not accessible through accepts_nested_attributes_for [#5939 state:resolved]
- 5939 attr_accessor not accessible through accepts_nested_attributes_for [#5939 state:resolved]