Class Index [+]

Quicksearch

ActiveSupport::Callbacks

Callbacks are code hooks that are run at key points in an object’s lifecycle. The typical use case is to have a base class define a set of callbacks relevant to the other functionality it supplies, so that subclasses can install callbacks that enhance or modify the base functionality without needing to override or redefine methods of the base class.

Mixing in this module allows you to define the events in the object’s lifecycle that will support callbacks (via ClassMethods.define_callbacks), set the instance methods, procs, or callback objects to be called (via ClassMethods.set_callback), and run the installed callbacks at the appropriate times (via run_callbacks).

Three kinds of callbacks are supported: before callbacks, run before a certain event; after callbacks, run after the event; and around callbacks, blocks that surround the event, triggering it when they yield. Callback code can be contained in instance methods, procs or lambdas, or callback objects that respond to certain predetermined methods. See ClassMethods.set_callback for details.

Example

  class Record
    include ActiveSupport::Callbacks
    define_callbacks :save

    def save
      run_callbacks :save do
        puts "- save"
      end
    end
  end

  class PersonRecord < Record
    set_callback :save, :before, :saving_message
    def saving_message
      puts "saving..."
    end

    set_callback :save, :after do |object|
      puts "saved"
    end
  end

  person = PersonRecord.new
  person.save

Output:

  saving...
  * save
  saved

Public Instance Methods

run_callbacks(kind, *args, &block) click to toggle source

Runs the callbacks for the given event.

Calls the before and around callbacks in the order they were set, yields the block (if given one), and then runs the after callbacks in reverse order. Optionally accepts a key, which will be used to compile an optimized callback method for each key. See ClassMethods.define_callbacks for more information.

If the callback chain was halted, returns false. Otherwise returns the result of the block, or true if no block is given.

  run_callbacks :save do
    save
  end
    # File lib/active_support/callbacks.rb, line 80
80:     def run_callbacks(kind, *args, &block)
81:       send("_run_#{kind}_callbacks", *args, &block)
82:     end

Private Instance Methods

_compile_filter(filter) click to toggle source

Filters support:

  Arrays::  Used in conditions. This is used to specify
            multiple conditions. Used internally to
            merge conditions from skip_* filters
  Symbols:: A method to call
  Strings:: Some content to evaluate
  Procs::   A proc to call with the object
  Objects:: An object with a before_foo method on it to call

All of these objects are compiled into methods and handled the same after this point:

  Arrays::  Merged together into a single filter
  Symbols:: Already methods
  Strings:: class_eval'ed into methods
  Procs::   define_method'ed into methods
  Objects::
    a method is created that calls the before_foo method
    on the object.
     # File lib/active_support/callbacks.rb, line 287
287:       def _compile_filter(filter)
288:         method_name = "_callback_#{@kind}_#{next_id}"
289:         case filter
290:         when Array
291:           filter.map {|f| _compile_filter(f)}
292:         when Symbol
293:           filter
294:         when String
295:           "(#{filter})"
296:         when Proc
297:           @klass.send(:define_method, method_name, &filter)
298:           return method_name if filter.arity <= 0
299: 
300:           method_name << (filter.arity == 1 ? "(self)" : " self, Proc.new ")
301:         else
302:           @klass.send(:define_method, "#{method_name}_object") { filter }
303: 
304:           _normalize_legacy_filter(kind, filter)
305:           scopes = Array.wrap(chain.config[:scope])
306:           method_to_call = scopes.map{ |s| s.is_a?(Symbol) ? send(s) : s }.join("_")
307: 
308:           @klass.class_eval             def #{method_name}(&blk)              #{method_name}_object.send(:#{method_to_call}, self, &blk)            end, __FILE__, __LINE__ + 1
309: 
310:           method_name
311:         end
312:       end
_compile_options(options) click to toggle source

Options support the same options as filters themselves (and support symbols, string, procs, and objects), so compile a conditional expression based on the options

     # File lib/active_support/callbacks.rb, line 252
252:       def _compile_options(options)
253:         conditions = ["true"]
254: 
255:         unless options[:if].empty?
256:           conditions << Array.wrap(_compile_filter(options[:if]))
257:         end
258: 
259:         unless options[:unless].empty?
260:           conditions << Array.wrap(_compile_filter(options[:unless])).map {|f| "!#{f}"}
261:         end
262: 
263:         conditions.flatten.join(" && ")
264:       end
_normalize_legacy_filter(kind, filter) click to toggle source
     # File lib/active_support/callbacks.rb, line 318
318:       def _normalize_legacy_filter(kind, filter)
319:         if !filter.respond_to?(kind) && filter.respond_to?(:filter)
320:           filter.singleton_class.class_eval             def #{kind}(context, &block) filter(context, &block) end, __FILE__, __LINE__ + 1
321:         elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around
322:           def filter.around(context)
323:             should_continue = before(context)
324:             yield if should_continue
325:             after(context)
326:           end
327:         end
328:       end
halted_callback_hook(filter) click to toggle source

A hook invoked everytime a before callback is halted. This can be overriden in AS::Callback implementors in order to provide better debugging/logging.

    # File lib/active_support/callbacks.rb, line 89
89:     def halted_callback_hook(filter)
90:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.