module ActiveModel::Callbacks - activemodel-4.2.3 Documentation

# module ActiveModel::Callbacks

## Active Model Callbacks¶ ↑

Provides an interface for any class to have Active Record like callbacks.

Like the Active Record methods, the callback chain is aborted as soon as one of the methods in the chain returns `false`.

First, extend ActiveModel::Callbacks from the class you are creating:

    class MyModel
      extend ActiveModel::Callbacks
    end

Then define a list of methods that you want callbacks attached to:

    define_model_callbacks :create, :update

This will provide all three standard callbacks (before, around and after) for both the `:create` and `:update` methods. To implement, you need to wrap the methods you want callbacks on in a block so that the callbacks get a chance to fire:

    def create
      run_callbacks :create do
        # Your create action methods here
      end
    end

Then in your class, you can use the `before_create`, `after_create` and `around_create` methods, just as you would in an Active Record model.

    before_create :action_before_create

    def action_before_create
      # Your code here
    end

When defining an around callback remember to yield to the block, otherwise it won't be executed:

    around_create :log_status

    def log_status
      puts 'going to call the block...'
      yield
      puts 'block successfully called.'
    end

You can choose not to have all three callbacks by passing a hash to the `define_model_callbacks` method.

    define_model_callbacks :create, only: [:after, :before]

Would only create the `after_create` and `before_create` callback methods in your class.

### Public Instance Methods

define_model_callbacks(*callbacks) click to toggle source

#define_model_callbacks accepts the same options `define_callbacks` does, in case you want to overwrite a default. Besides that, it also accepts an `:only` option, where you can choose if you want all types (before, around or after) or just some.

    define_model_callbacks :initializer, only: :after

Note, the `only: <type>` hash will apply to all callbacks defined on that method call. To get around this you can call the #define_model_callbacks method as many times as you need.

    define_model_callbacks :create,  only: :after
    define_model_callbacks :update,  only: :before
    define_model_callbacks :destroy, only: :around

Would create `after_create`, `before_update` and `around_destroy` methods only.

You can pass in a class to before_<type>, after_<type> and around_<type>, in which case the callback will call that class's <action>_<type> method passing the object that the callback is being called on.

    class MyModel
      extend ActiveModel::Callbacks
      define_model_callbacks :create

      before_create AnotherClass
    end

    class AnotherClass
      def self.before_create( obj )
        # obj is the MyModel instance that the callback is being called on
      end
    end

NOTE: `method_name` passed to `define_model_callbacks` must not end with `!`, `?` or `=`.

    # File lib/active_model/callbacks.rb, line 103
    def define_model_callbacks(*callbacks)
      options = callbacks.extract_options!
      options = {
        terminator: ->(_,result) { result == false },
        skip_after_callbacks_if_terminated: true,
        scope: [:kind, :name],
        only: [:before, :around, :after]
      }.merge!(options)

      types = Array(options.delete(:only))

      callbacks.each do |callback|
        define_callbacks(callback, options)

        types.each do |type|
          send("_define_#{type}_model_callback", self, callback)
        end
      end
    end