Module: ActiveModel::Callbacks
| Relationships & Source Files | |
| Extension / Inclusion / Inheritance Descendants | |
|
Included In:
| |
| Defined in: | activemodel/lib/active_model/callbacks.rb |
Overview
========================
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 throws :abort.
First, extend 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 to have only specific 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.
NOTE: Defining the same callback multiple times will overwrite previous callback definitions.
Class Method Summary
- .extended(base) Internal use only
Instance Method Summary
-
#define_model_callbacks(*callbacks)
#define_model_callbacks accepts the same options
define_callbacksdoes, in case you want to overwrite a default. - #_define_after_model_callback(klass, callback) private
- #_define_around_model_callback(klass, callback) private
- #_define_before_model_callback(klass, callback) private
Class Method Details
.extended(base)
# File 'activemodel/lib/active_model/callbacks.rb', line 80
def self.extended(base) # :nodoc: base.class_eval do include ActiveSupport::Callbacks end end
Instance Method Details
#_define_after_model_callback(klass, callback) (private)
[ GitHub ]# File 'activemodel/lib/active_model/callbacks.rb', line 163
def _define_after_model_callback(klass, callback) klass.define_singleton_method("after_#{callback}") do |*args, **, &block| .assert_valid_keys(:if, :unless, :prepend) [:prepend] = true conditional = ActiveSupport::Callbacks::Conditionals::Value.new { |v| v != false } [:if] = Array([:if]) + [conditional] set_callback(:"#{callback}", :after, *args, , &block) end end
#_define_around_model_callback(klass, callback) (private)
[ GitHub ]# File 'activemodel/lib/active_model/callbacks.rb', line 156
def _define_around_model_callback(klass, callback) klass.define_singleton_method("around_#{callback}") do |*args, **, &block| .assert_valid_keys(:if, :unless, :prepend) set_callback(:"#{callback}", :around, *args, , &block) end end
#_define_before_model_callback(klass, callback) (private)
[ GitHub ]# File 'activemodel/lib/active_model/callbacks.rb', line 149
def _define_before_model_callback(klass, callback) klass.define_singleton_method("before_#{callback}") do |*args, **, &block| .assert_valid_keys(:if, :unless, :prepend) set_callback(:"#{callback}", :before, *args, , &block) end end
#define_model_callbacks(*callbacks)
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 :initialize, only: :after
Note, the only: 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_
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 'activemodel/lib/active_model/callbacks.rb', line 129
def define_model_callbacks(*callbacks) = callbacks. = { skip_after_callbacks_if_terminated: true, scope: [:kind, :name], only: [:before, :around, :after] }.merge!() types = Array(.delete(:only)) callbacks.each do |callback| define_callbacks(callback, ) types.each do |type| send("_define_#{type}_model_callback", self, callback) end end end