Plugin - without_callbacks

ActiveRecord callbacks can be extremely useful, but sometimes they
just get in the way.  Wouldn't it be nice if you could disable the
callbacks at will?  Well, now you can!

Installation

script/plugin install git://github.com/brentmc79/without_callbacks.git



Example

Given an AR model like so:

 

class ShamWowGuy < ActiveRecord::Base

  before_save :slap_chop
  before_update :punch_hooker

  protected
    def punch_hooker
      self.hooker_count = hooker_count+1
    end
    def slap_chop
      self.catchphrase = "You're gonna love my nuts!"
    end
end


What happens when you create/save the model?



When the model is saved, its catchphrase attribute is updated by the
callback just prior to being persisted to the database.

Maybe your Mom came by for a visit and you don't really want Vince,
the ShamWow guy, blurting offensive comments about his nuts.  Well,
here's what you do:

vince = ShamWowGuy.new(:catchphrase => "You'll say WOW evey time!")
ShamWowGuy.without_callbacks(:slap_chop) do
  vince.save
end
vince.catchphrase #=> "You'll say WOW evey time!"


Uh-oh, there's a typo in our catchphrase, so we need to update
vince.  Mom's still here and she doesn't approve of hooker-punching.
What's a girl to do?

We can pass in both callback method names, like so:

ShamWowGuy.without_callbacks(:slap_chop, :punch_hooker) do
  vince.save
end


Or, we can disable ALL callbacks by not passing any arguments:

ShamWowGuy.without_callbacks do
  vince.save
end


That's all there is to it!

 

Note

At the moment, without_callbacks only disables instance methods
defined within the specified class.  Procs or eval'd strings
like this:

before_save {|sham_wow_guy| sham_wow_guy.slap_chop }

OR

before_update 'self.hooker_count = nil'

in the callback class methods are not yet handled.

 

 

Comments (5)


avatar

Nice README. But.....uh.

avatar

This is by far the best plugin README ever.

avatar

What? You guys have never seen code samples before?

avatar

It was great for me too until I started using multi-threading. Unfortunately it is not threadsafe.

avatar

Just for the records. Ruby / Jruby is always running in a thread which you can get with: Thread.current You can assign variables as such: Thread.current[:callbacks_enabled] = true And read them as such: Thread.current[:callbacks_enabled] This allows your callbacks to find out if they should be doing anything or not. ie. def some_callback if Thread.current[:callbacks_enabled] # do some callback stuff end end Doing it like this is totally thread safe, less code to go wrong and easier to understand what is happening. Don't forget that some method needs to set the Thread.current[:callbacks_enabled] = false and set it to true when you need your callbacks working again. However, saying that, some people say that if you have to disable your callbacks then you have a design problem. Others don't agree. I must say that I now very much belong to the group of people that say you have a design problem if you need handle callbacks like this. Reconsider your design - i guarantee that you can do what ever you need to do without having to disable callbacks and your solution will also have less code.

Leave a Comment


 Name is required
 Email is required