Never been to DZone Snippets before?

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Custom Rails Callback (See related posts)

// This shows you how to extend active record to allow a custom callback.

#ever needed to add your own callback into the active record callback chain?
#here's how...
module ActiveRecord
  
  #to keep things clean we'll define our own module
  module SweetCustomCallbacks
    
    #this is the ruby method that is called when you call include on a module
    #the method passed, base in our case, is the class your including yourself in
    def self.included(base)
      
      #this clas_eval method takes a block that will be added to base, which is ActiveRecord::Base
      #basically this is like writing code directly into the class ActiveRecord::Base
      base.class_eval do
        
        #alias_method_chain is very cool
        #it allows us override a method without removing the original and without the original knowing its been changed
        #here's how it works:
        # 1st argument is the name of the method you're overriding
        # 2nd argument is feature you want to add
        # so if create_or_update is called it will actually call create_or_update_with_sweet_custom_callbacks
        # the original is still avaliable at create_or_update_without_custom_callbacks
        
        alias_method_chain :create_or_update, :sweet_custom_callbacks
        #the method create_or_update is an internals method to ActiveRecord that is called whenever you call .save or .update
        
        #this is the class method that allows the cool syntax:
        # class Article < ActiveRecord::Base
        # before_before_save :add_authors_name
        #private
        #def add_authors_name
        #.....
        def self.before_before_save(*callbacks, &block)
          callbacks << block if block_given? #add the block to the array of callback functions if a block was passed
          write_inheritable_array(:before_before_save,callbacks) 
        end
      end
    end
    
    #the instance method, although not recomended is avaliable for overriding
    #also if you wanted to have a callback that always did something say add the users's id to the object 
    #you could always code that in here and remove the class above
    def before_before_save() end

    #ok this is the method that is now called instead of create_or_update
    #it calls a method callback on 
    def create_or_update_with_sweet_custom_callbacks
      return false if callback(:before_before_save) == false  #this method does all the real work and calls the callback function in callbacks.rb that gets the methods and runs them 
      create_or_update_without_sweet_custom_callbacks
    end
    
   end
 
   class Base    
     include SweetCustomCallbacks #include our module in ActiveRecord::Base
   end
end

Comments on this post

elliottcable posts on Mar 13, 2008 at 17:18
I won't be using this in activerecord (hate rails) - but possibly somewhere else! Really sexy d-:
mcmire posts on Mar 21, 2008 at 00:26
Unfortunately alias_method_chain and write_inheritable_array are Railsisms, so you'd have to implement them yourself if you really wanted to do that. Also callback is a private method in AR::Base.

You need to create an account or log in to post comments to this site.


Click here to browse all 5144 code snippets

Related Posts