Skipping ActiveRecord Callback Methods
December 12th, 2007
ActiveRecord provides a great way to tie into a model's lifecycle through various callbacks. However, in certain cases you may want to skip specific callbacks you've defined on a model similar to skipping filters in ActionController. Rails doesn't support this natively, but its very easy to extend ActiveRecord to add this feature. The solution we ended up using was inspired by this post on thatswhatimtalkingabout.org.
Frist, we'll need to open up ActiveRecord and add the method that will allow us to skip the callback. There are a few ways you can go about doing this, but we use an initializer. So create a file in config/initializers called active_record_extensions.rb with the following code:
class ActiveRecord::Base
def self.skip_callback(callback, &block)
method = instance_method(callback)
remove_method(callback) if respond_to?(callback)
define_method(callback){ true }
yield
remove_method(callback)
define_method(callback, method)
end
end
All this code does is store off the callback method, yields the passed in block and then adds the callback back in.
So, lets say we have the following model...
class User < ActiveRecord::Base after_create :send_notification end
You may have some process that is creating Users where you don't want the notification to be sent after the user gets created. In order to do this, simply wrap your create or save in the skip_callback method like so:
User.skip_callback(:send_notification) do User.create(:name => 'Josh') endNow you've successfully created a User without the send_notification callback getting executed.
