iie labs

How to Use Callback Classes

Posted over 4 years ago by Philip Ingram

I had a need to reuse an after_create callback over two different Models. Smelling something off, i wondered if there was a way to DRY this part of my code, as I like to reuse when i can. Although i’m not a maniac about it, to me it seems that reusing a callback is something that you’d want to keep DRY.

Off i went to the mainstay of rails knowledge the Rails Guides , and i found this bit of instruction, on which this post will elaborate.

Introducing Callback Classes

To refresh, a callback is used when you want to execute additional code after a record has been created or updated. This is some fascinating stuff, and well worth reading into. For example, these callbacks are used to update additional attributes based on a new record being created and it tidies up your code immensely.

Callback classes take this thinking a step further by allowing you to create a Class for the Callback and refer to this Class within your various different models.

Example of Callback Classes in use

I needed to generate a unique code after a certain model was created.

First, I created a file within app/models called unique_code_callbacks.rb.

Since there were two models where this code could be created, so streamlining the code this way made sense for me. I added this code to the new file i just created:


class UniqueCodeCallbacks
  def self.after_create(something)
    self.unique_unique_code(something)
  end
  #make a unique code
  def self.unique_unique_code(blah)
    if blah.class == TaxInfo
      self.make_unique_code(blah.company_info.user) if blah.company_info.user.unique_code.blank?
    else
      self.make_unique_code(blah.user) if blah.address.country != "US" && blah.user.unique_code.blank?
    end
  end
  protected
  def self.make_unique_code(user)
    user.update_attribute(:unique_code, self.make_token)
  end
  def self.secure_digest(*args)
    Digest::SHA1.hexdigest(args.flatten.join('--'))
  end
  def self.make_token
    self.secure_digest(Time.now, (1..10).map{ rand.to_s })
  end
end

I'm using the latter example from the rails guide, but i’m also extending what they have shown you by adding all my logic within this class too. A couple of gotchas to watch out for:

  • make sure you add self.method to all the methods within this class
  • you need to pass something to the after_create callback, or you’ll receive an error calling for 1 when 0 expected , as that drove me nuts. Someone may comment why that is, if you know.

Using the Callback Class in your models

To use this great callback, all you have to do is add code like this to your model:


class TaxInfo < ActiveRecord::Base
  after_create UniqueCodeCallbacks
end

I’ve only created the after_create callback in this class, but you could have an after_update too, just add it to the class and bob is your uncle… really he is, you should call him.

Enjoy.

Comments

blog comments powered by Disqus