This project is archived and is in readonly mode.
Observer callback ordering with touched associations is unexpected
-
Geoff Garside
I believe I've managed to determine the cause for this. Using the classes from the provided test as an example when we do the following
bunny = Bunny.new({:name => "foo", carrot_attributes => [{:rating => 0.2}]}) bunny.savewhat happens is the following
- The Bunny instance is persisted to the database
- The Carrot instance on bunny is persisted to the database,
either as part of the create or an early after_save
callback
- The belongs_to_touch_after_save_or_destroy_for_bunny Carrot
after_save callback is run
- belongs_to_touch_after_save_or_destroy_for_bunny calls save! on
the bunny object
- bunny.save! as the object has been persisted to the database
performs an UPDATE of the database
- The BunnyObserver is notified of an UPDATE having occurred and
runs its after_update and after_save callbacks
- The adding of the Carrot instance to the Bunny returns
- The Bunny instance save method which is creating the object
runs its after_* callbacks
- The BunnyObserver is notified of an INSERT having occurred and runs its after_create and after_save callbacks
So the call sequence is logical with this understanding, however my expectation for the observer call sequence is different from the resulting sequence.
- The Bunny instance is persisted to the database
-
Geoff Garside
I'm not sure at the moment how to fix this within rails itself, for now though I've got the following to work in my observer
class BunnyObserver < ActiveRecord::Observer def after_create(record) # .. do something with record .. end def after_update(record) return if in_create_stack? # .. do something with record .. end private def in_create_stack? caller.any? {|c| c =~ /`create'/ } end endits a bit of a hack with an aroma of roquefort but it is at the very least working and would seem to function in both Ruby 1.8 and Ruby 1.9.
If any better solutions or fixes can be offered then I'd be happy to add a better aroma to my code.
-
Rohit Arondekar
- State changed from new to stale
- Importance changed from to Low
Marking ticket as stale. If this is still an issue please leave a comment with suggested changes, creating a patch with tests, rebasing an existing patch or just confirming the issue on a latest release or master/branches.
