This project is archived and is in readonly mode.

ActiveRecord observers can't be used for "before" callbacks
Reported by Mislav | March 2nd, 2010 @ 05:30 AM
ActiveRecord::Observer hooks into observed models by registering
a _notify_observers_for_#{method} callback on them,
which calls notify_observers(:#{method}). For a
before_create, this would result in something
like:
## in MyModel
def _notify_observers_for_before_create
  notify_observers(:before_create)
end
before_create :_notify_observers_for_before_create
The problem is, the underlying implementation uses Observable
module from Ruby stdlib, which implements
notify_observers in a way that it returns false on
success. Needless to say, this halts the callback chain on "before"
callbacks and the record is not saved.
Comments and changes to this ticket
- 
            
         Mislav March 2nd, 2010 @ 06:11 AM- Tag changed from activerecord, callbacks, observers to activerecord, callbacks, observers, rails3
 
- 
         Sven Fuchs March 2nd, 2010 @ 09:07 AMGosh, I ran into the same thing today. As long as you don't care about the return value this hax seems to work for now ActiveRecord::Observer.class_eval do def add_observer!(klass) super self.class.observed_methods.each do |method| callback = :"_notify_observers_for_#{method}" if (klass.instance_methods & [callback, callback.to_s]).empty? klass.class_eval "def #{callback}; notify_observers(:#{method}); true; end" klass.send(method, callback) end end end end
- 
            
         
- 
         Yehuda Katz (wycats) March 27th, 2010 @ 11:12 AM- Assigned user set to Yehuda Katz (wycats)
 
- 
            
         Mislav April 16th, 2010 @ 04:21 PM- Tag changed from activerecord, callbacks, observers, rails3 to activerecord, callbacks, observers, rails3, regression
 Failing test 
- 
            
         Mislav April 16th, 2010 @ 06:55 PMTaken a stab at fixing this. This patch includes changes from the above patch. Detailed explanation of the changes in commit messages, but here is the last (and most important): improve how ActiveRecord::Observer defines callbacks on observed models Instead of using a single notify_observerscall for every callback type, each observer now registers a unique callback for itself. Example:before_save :_notify_user_observer_for_before_save def _notify_user_observer_for_before_save observer.update(:before_save, self) endBenefit: "before" callbacks halt when observer.updatereturns false. This way, ActiveRecord observers can prevent records from saving.
- 
         Repository April 16th, 2010 @ 09:54 PM- State changed from new to committed
 (from [2161b8745a22379356b466a60b9aa763c0593f9b]) improve how ActiveRecord::Observer defines callbacks on observed models Instead of using a single notify_observerscall for every callback type,
 each observer now registers a unique callback for itself. Example:before_save :_notify_user_observer_for_before_save def _notify_user_observer_for_before_save observer.update(:before_save, self)end Benefit: "before" callbacks halt when observer.updatereturns false.
 This way, ActiveRecord observers can prevent records from saving.[#4087 state:committed] Signed-off-by: Jeremy Kemper jeremy@bitsweat.net 
 http://github.com/rails/rails/commit/2161b8745a22379356b466a60b9aa7...
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
- 
         4087 
          ActiveRecord observers can't be used for "before" callbacks
        [#4087 state:committed] 4087 
          ActiveRecord observers can't be used for "before" callbacks
        [#4087 state:committed]
 Anil Wadghule
      Anil Wadghule
 Cesario
      Cesario
 Mislav
      Mislav
 Yehuda Katz (wycats)
      Yehuda Katz (wycats)