This project is archived and is in readonly mode.
accepts_nested_attributes_for with :touch => ture cause ActiveRecord::StaleObjectError
-
tankwanghow
Sorry about the formatting, this is better.
class Invoice < ActiveRecord::Base has_many :line_items accepts_nested_attributes_for :line_items end class LineItem < ActiveRecord::Base belongs_to :invoice, :touch => true endI have found a solution from UVSoft plugins :-
http://github.com/UVSoft/improved_touch http://github.com/UVSoft/touching_nested_attributes
I found this plugin is very useful, can these plugins be made it to the rails core?
-
Ivan Ukhov
Here is my patch. This is also useful for fragment caching with cach-keys based on timestamps (<% cache @record do %> <% end %>). When fragments include information not only about the record itself, but also about its association, and when you update nested attributes without updating record, the fragments do not expire, but they should. This patch touch the record without saving when nested attributes are being changed.
-
Eloy Duran
Seems valid, however, you patch is lacking test coverage. Could you please add tests to the patch?
Also, it seems by glancing over the patch that this would always touch the parent, whereas I'd expect that to only happen if
:touch => true' was set on the parent. Or did I misinterpret the code? -
Ivan Ukhov
Yes, the patch really touches always. In my case I don't use :touch => true at all, that's why I haven't implement this option. And about testing, to my shame, I dont know how to do it.
-
tankwanghow
Using UVSoft timestamp.rb patch, I have added a feature in accepts_nested_attributes_for method in nested_attribute.rb, which will add an attr_accessor :silent to the association model. Then added check condition in associations.rb in add_touch_callbacks method to check for silent attribute is true, then the touch callback will execute the update_timestamp method in timestamp.rb, Yes touch will be call multiple time, with :_silent => true, save! will not be call, thus solved the ActiveRecord::StaleObjectError
In the view files, just add a hidden field named :_silent
@@@ruby object.hidden_field :_silent, :value => true
-
tankwanghow
the belongs_to :invoice, :touch => true can still be use.
-
tankwanghow
Sorry, I have submitted the wrong patch.
This is the correct one.
Please Review, I think this feature is very useful for optimistic locking in nested_attributes and javascript style of multiple-models form.
If you are already using accepts_nested_attributes_for like the following :-
class Invoice < ActiveRecord::Base has_many :line_items accepts_nested_attributes_for :line_items end class LineItem < ActiveRecord::Base belongs_to :invoice, :touch => true endNo code need to be change in the model or the controller.
In your view just add a
to your nested_attribute (ie. LineItem view)hidden_field :_silent_touch, :value => trueThen optimistic locking will work on nested attributes form.
I am not good in writing test-unit can anyone help!!!
Thank You,
-
tankwanghow
- Tag changed from accepts_nested_attributes_for, active_record, touch to accepts_nested_attributes_for, active_record, locking, optimistic, touch
-
Eloy Duran
- State changed from new to incomplete
It would be great if you could extract a small applications showing the problem and your solution. Then I'll be able to write the appropriate test coverage and judge the patch.
-
tankwanghow
Thank for your concern on my problem.
Here is the two rails application opt_lock_nest_problem.tar.gz and opt_lock_nest_solution.tar.gz
In order for the solution to work, you have to add the nested_attributes_silent_touch patch.
But I am still having problem with lock_version, in my last two spec.
Please review and advise.
Thank you
-
tankwanghow
I have found a problem with my patch, let me fix the bug and I will send a new patch.
-
Eloy Duran
Thanks for the update. I'll await your new patch.
-
tankwanghow
- Tag changed from accepts_nested_attributes_for, active_record, locking, optimistic, touch to accepts_nested_attributes_for, active_record, locking, optimistic, patch, touch
Sorry for the delay, hopefully this time, I get it right...
Sample application opt_lock_nest.zip and the patch fix_nested_opt_lock.diff
Run the project_spec.rb before the patch -> all specs fail
After the patch, run the spec again -> all specs passThank you
-
Eloy Duran
Thanks for the application. I;ve ran it against 2.3.5 and see the StaleObjectError's. However, if I run it against the current 2-3-stable branch, I don't get these errors. The specs still fail though, but it's because the lock_version doesn't match the expected versions.
The output I get:
% spec spec/models/project_spec.rb FFFF 1) 'Project when save with nested attributes should not have STALE object error and :lock_version should be 0' FAILED expected: 0, got: 3 (using ==) ./spec/models/project_spec.rb:15: 2) 'Project when save with nested attributes should not have STALE object error and :lock_version should be 7' FAILED expected: 7, got: 8 (using ==) ./spec/models/project_spec.rb:38: 3) 'Project when save with nested attributes should not have STALE object error and :lock_version should be 0' FAILED expected: 0, got: 2 (using ==) ./spec/models/project_spec.rb:48: 4) 'Project when save with nested attributes should not have STALE object error and :lock_version should be 4' FAILED expected: 4, got: 5 (using ==) ./spec/models/project_spec.rb:66: Finished in 0.332062 seconds 4 examples, 4 failuresCould you check that, if it now works as you'd want, and if the versions not matching exactly is irrelevant or not?
In order to check that out do the following in the application source root:
cd vendor git clone git://github.com/rails/rails.git cd rails git checkout 2-3-stableThanks!
-
tankwanghow
As long as, optimistic locking is working with :touch => true for nested_attributes I don't worry about the lock_version number.
So the new rails 2-3-stable WORKS !!!
Thank You
