lib/active_model/callbacks.rb in activemodel-3.2.22.5 vs lib/active_model/callbacks.rb in activemodel-4.0.0.beta1

- old
+ new

@@ -1,15 +1,14 @@ -require 'active_support/core_ext/array/wrap' -require 'active_support/callbacks' +require 'active_support/core_ext/array/extract_options' module ActiveModel - # == Active Model 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. + # one of the methods in the chain returns +false+. # # First, extend ActiveModel::Callbacks from the class you are creating: # # class MyModel # extend ActiveModel::Callbacks @@ -17,62 +16,76 @@ # # 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: + # This will provide all three standard callbacks (before, around and after) + # for both the <tt>:create</tt> and <tt>:update</tt> 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 module. + # Then in your class, you can use the +before_create+, +after_create+ and + # +around_create+ methods, just as you would in an Active Record module. # # 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+ method. # - # define_model_callbacks :create, :only => [:after, :before] + # define_model_callbacks :create, only: [:after, :before] # - # Would only create the after_create and before_create callback methods in your - # class. + # Would only create the +after_create+ and +before_create+ callback methods in + # your class. module Callbacks - def self.extended(base) + def self.extended(base) #:nodoc: base.class_eval do include ActiveSupport::Callbacks end end - # 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 accepts the same options +define_callbacks+ does, + # in case you want to overwrite a default. Besides that, it also accepts an + # <tt>:only</tt> option, where you can choose if you want all types (before, + # around or after) or just some. # - # define_model_callbacks :initializer, :only => :after + # define_model_callbacks :initializer, only: :after # - # Note, the <tt>:only => <type></tt> hash will apply to all callbacks defined on - # that method call. To get around this you can call the define_model_callbacks + # Note, the <tt>only: <type></tt> 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 + # 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. + # 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. + # 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 # @@ -82,30 +95,32 @@ # class AnotherClass # def self.before_create( obj ) # # obj is the MyModel instance that the callback is being called on # end # end - # def define_model_callbacks(*callbacks) options = callbacks.extract_options! options = { - :terminator => "result == false", - :scope => [:kind, :name], - :only => [:before, :around, :after] - }.merge(options) + :terminator => "result == false", + :skip_after_callbacks_if_terminated => true, + :scope => [:kind, :name], + :only => [:before, :around, :after] + }.merge!(options) - types = Array.wrap(options.delete(:only)) + 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 + private + def _define_before_model_callback(klass, callback) #:nodoc: klass.class_eval <<-CALLBACK, __FILE__, __LINE__ + 1 def self.before_#{callback}(*args, &block) set_callback(:#{callback}, :before, *args, &block) end @@ -123,10 +138,10 @@ def _define_after_model_callback(klass, callback) #:nodoc: klass.class_eval <<-CALLBACK, __FILE__, __LINE__ + 1 def self.after_#{callback}(*args, &block) options = args.extract_options! options[:prepend] = true - options[:if] = Array.wrap(options[:if]) << "!halted && value != false" + options[:if] = Array(options[:if]) << "value != false" set_callback(:#{callback}, :after, *(args << options), &block) end CALLBACK end end