2009-02-27 18:11:02 -05:00
module AbstractController
module Callbacks
2009-05-28 12:35:36 -04:00
extend ActiveSupport :: Concern
2009-05-07 11:38:57 -04:00
2009-10-12 23:15:43 -04:00
# Uses ActiveSupport::Callbacks as the base functionality. For
2009-06-08 19:14:38 -04:00
# more details on the whole callback system, read the documentation
2009-10-12 23:15:43 -04:00
# for ActiveSupport::Callbacks.
include ActiveSupport :: Callbacks
2009-05-07 11:38:57 -04:00
included do
2013-05-14 19:03:09 -04:00
define_callbacks :process_action ,
2014-10-16 19:21:24 -04:00
terminator : - > ( controller , result_lambda ) { result_lambda . call if result_lambda . is_a? ( Proc ) ; controller . response_body } ,
2013-05-14 19:03:09 -04:00
skip_after_callbacks_if_terminated : true
2009-02-27 22:25:45 -05:00
end
2009-05-07 11:38:57 -04:00
2009-06-08 19:14:38 -04:00
# Override AbstractController::Base's process_action to run the
# process_action callbacks around the normal behavior.
2011-05-06 12:39:10 -04:00
def process_action ( * args )
2012-05-10 03:56:36 -04:00
run_callbacks ( :process_action ) do
2009-02-27 22:25:45 -05:00
super
end
end
2009-05-28 10:49:02 -04:00
2009-02-27 22:25:45 -05:00
module ClassMethods
2014-12-19 15:49:50 -05:00
# If +:only+ or +:except+ are used, convert the options into the
# +:if+ and +:unless+ options of ActiveSupport::Callbacks.
#
# The basic idea is that <tt>:only => :index</tt> gets converted to
# <tt>:if => proc {|c| c.action_name == "index" }</tt>.
2009-06-08 19:14:38 -04:00
#
2014-04-01 13:40:04 -04:00
# Note that <tt>:only</tt> has priority over <tt>:if</tt> in case they
# are used together.
#
# only: :index, if: -> { true } # the :if option will be ignored.
#
2015-01-08 12:30:31 -05:00
# Note that <tt>:if</tt> has priority over <tt>:except</tt> in case they
# are used together.
#
# except: :index, if: -> { true } # the :except option will be ignored.
#
2009-06-08 19:14:38 -04:00
# ==== Options
2015-11-14 13:40:02 -05:00
# * <tt>only</tt> - The callback should be run only for this action.
# * <tt>except</tt> - The callback should be run for all actions except this action.
2009-02-27 22:25:45 -05:00
def _normalize_callback_options ( options )
2012-11-09 08:41:11 -05:00
_normalize_callback_option ( options , :only , :if )
_normalize_callback_option ( options , :except , :unless )
end
def _normalize_callback_option ( options , from , to ) # :nodoc:
if from = options [ from ]
2015-12-15 07:12:16 -05:00
_from = Array ( from ) . map ( & :to_s ) . to_set
from = proc { | c | _from . include? c . action_name }
2013-08-07 15:43:22 -04:00
options [ to ] = Array ( options [ to ] ) . unshift ( from )
2009-02-27 22:25:45 -05:00
end
end
2009-05-28 10:49:02 -04:00
2014-05-27 18:08:23 -04:00
# Skip before, after, and around action callbacks matching any of the names.
2009-06-08 19:14:38 -04:00
#
# ==== Parameters
2010-08-25 12:57:27 -04:00
# * <tt>names</tt> - A list of valid names that could be used for
2009-06-08 19:14:38 -04:00
# callbacks. Note that skipping uses Ruby equality, so it's
# impossible to skip a callback defined using an anonymous proc
2015-11-14 13:40:02 -05:00
# using #skip_action_callback.
2012-12-07 12:54:26 -05:00
def skip_action_callback ( * names )
2015-10-28 00:20:23 -04:00
ActiveSupport :: Deprecation . warn ( '`skip_action_callback` is deprecated and will be removed in Rails 5.1. Please use skip_before_action, skip_after_action or skip_around_action instead.' )
2015-02-21 09:37:07 -05:00
skip_before_action ( * names , raise : false )
skip_after_action ( * names , raise : false )
skip_around_action ( * names , raise : false )
2009-06-01 18:40:11 -04:00
end
2015-01-08 15:51:51 -05:00
def skip_filter ( * names )
2015-02-26 19:03:31 -05:00
ActiveSupport :: Deprecation . warn ( " `skip_filter` is deprecated and will be removed in Rails 5.1. Use skip_before_action, skip_after_action or skip_around_action instead. " )
2015-01-08 15:51:51 -05:00
skip_action_callback ( * names )
end
2009-06-01 18:40:11 -04:00
2009-06-08 19:14:38 -04:00
# Take callback names and an optional callback proc, normalize them,
# then call the block with each callback. This allows us to abstract
# the normalization across several methods that use it.
#
# ==== Parameters
2010-08-25 12:57:27 -04:00
# * <tt>callbacks</tt> - An array of callbacks, with an optional
2009-06-08 19:14:38 -04:00
# options hash as the last parameter.
2010-08-25 12:57:27 -04:00
# * <tt>block</tt> - A proc that should be added to the callbacks.
2009-06-08 19:14:38 -04:00
#
# ==== Block Parameters
2015-11-14 13:40:02 -05:00
# * <tt>name</tt> - The callback to be added.
# * <tt>options</tt> - A hash of options to be used when adding the callback.
2012-02-23 02:25:31 -05:00
def _insert_callbacks ( callbacks , block = nil )
2013-07-02 07:35:18 -04:00
options = callbacks . extract_options!
2009-06-02 22:00:59 -04:00
_normalize_callback_options ( options )
2009-06-08 19:14:38 -04:00
callbacks . push ( block ) if block
callbacks . each do | callback |
yield callback , options
2009-06-02 22:00:59 -04:00
end
end
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: before_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: before_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback before actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: prepend_before_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: prepend_before_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Prepend a callback before actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: skip_before_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: skip_before_action(names)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Skip a callback before actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: append_before_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: append_before_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback before actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: after_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: after_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback after actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: prepend_after_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: prepend_after_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Prepend a callback after actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: skip_after_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: skip_after_action(names)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Skip a callback after actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: append_after_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: append_after_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback after actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: around_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: around_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback around actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: prepend_around_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: prepend_around_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Prepend a callback around actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: skip_around_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: skip_around_action(names)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Skip a callback around actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
##
2012-12-07 12:54:26 -05:00
# :method: append_around_action
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# :call-seq: append_around_action(names, block)
2011-08-11 15:43:48 -04:00
#
2012-12-07 12:54:26 -05:00
# Append a callback around actions. See _insert_callbacks for parameter details.
2011-08-11 15:43:48 -04:00
2012-12-07 12:54:26 -05:00
# set up before_action, prepend_before_action, skip_before_action, etc.
2009-06-08 19:14:38 -04:00
# for each of before, after, and around.
2012-12-07 12:54:26 -05:00
[ :before , :after , :around ] . each do | callback |
2013-05-26 10:49:17 -04:00
define_method " #{ callback } _action " do | * names , & blk |
_insert_callbacks ( names , blk ) do | name , options |
set_callback ( :process_action , callback , name , options )
end
end
2015-01-08 15:51:51 -05:00
define_method " #{ callback } _filter " do | * names , & blk |
2015-01-30 08:01:58 -05:00
ActiveSupport :: Deprecation . warn ( " #{ callback } _filter is deprecated and will be removed in Rails 5.1. Use #{ callback } _action instead. " )
2015-01-08 15:51:51 -05:00
send ( " #{ callback } _action " , * names , & blk )
end
2013-05-26 10:49:17 -04:00
define_method " prepend_ #{ callback } _action " do | * names , & blk |
_insert_callbacks ( names , blk ) do | name , options |
set_callback ( :process_action , callback , name , options . merge ( :prepend = > true ) )
end
end
2015-01-08 15:51:51 -05:00
define_method " prepend_ #{ callback } _filter " do | * names , & blk |
2015-01-30 08:01:58 -05:00
ActiveSupport :: Deprecation . warn ( " prepend_ #{ callback } _filter is deprecated and will be removed in Rails 5.1. Use prepend_ #{ callback } _action instead. " )
2015-01-08 15:51:51 -05:00
send ( " prepend_ #{ callback } _action " , * names , & blk )
end
2013-05-26 10:49:17 -04:00
# Skip a before, after or around callback. See _insert_callbacks
# for details on the allowed parameters.
define_method " skip_ #{ callback } _action " do | * names |
_insert_callbacks ( names ) do | name , options |
skip_callback ( :process_action , callback , name , options )
end
end
2015-01-08 15:51:51 -05:00
define_method " skip_ #{ callback } _filter " do | * names , & blk |
2015-01-30 08:01:58 -05:00
ActiveSupport :: Deprecation . warn ( " skip_ #{ callback } _filter is deprecated and will be removed in Rails 5.1. Use skip_ #{ callback } _action instead. " )
2015-01-08 15:51:51 -05:00
send ( " skip_ #{ callback } _action " , * names , & blk )
end
2013-05-26 10:49:17 -04:00
# *_action is the same as append_*_action
2014-06-03 18:53:28 -04:00
alias_method :" append_ #{ callback } _action " , :" #{ callback } _action "
2015-01-08 15:51:51 -05:00
define_method " append_ #{ callback } _filter " do | * names , & blk |
2015-01-30 08:01:58 -05:00
ActiveSupport :: Deprecation . warn ( " append_ #{ callback } _filter is deprecated and will be removed in Rails 5.1. Use append_ #{ callback } _action instead. " )
2015-01-08 15:51:51 -05:00
send ( " append_ #{ callback } _action " , * names , & blk )
end
2009-02-27 22:25:45 -05:00
end
end
2009-02-27 18:11:02 -05:00
end
2009-05-28 10:49:02 -04:00
end