aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport/lib
diff options
context:
space:
mode:
authorclaudiob <claudiob@gmail.com>2014-10-16 16:21:24 -0700
committerclaudiob <claudiob@gmail.com>2015-01-02 15:31:55 -0800
commit2386daabe7f8c979b453010dc0de3e1f6bbf859d (patch)
tree74ab7a4ffc32cda7126e3ce8950d21af0c4c4b90 /activesupport/lib
parent93dd5028a0cd0363d9f4bfc97d9ce70f0f3e88c8 (diff)
downloadrails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.tar.gz
rails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.tar.bz2
rails-2386daabe7f8c979b453010dc0de3e1f6bbf859d.zip
Throw :abort halts default CallbackChains
This commit changes arguments and default value of CallbackChain's :terminator option. After this commit, Chains of callbacks defined **without** an explicit `:terminator` option will be halted as soon as a `before_` callback throws `:abort`. Chains of callbacks defined **with** a `:terminator` option will maintain their existing behavior of halting as soon as a `before_` callback matches the terminator's expectation. For instance, ActiveModel's callbacks will still halt the chain when a `before_` callback returns `false`.
Diffstat (limited to 'activesupport/lib')
-rw-r--r--activesupport/lib/active_support/callbacks.rb23
1 files changed, 18 insertions, 5 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index d2911a254c..3a3061e536 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -142,8 +142,8 @@ module ActiveSupport
halted = env.halted
if !halted && user_conditions.all? { |c| c.call(target, value) }
- result = user_callback.call target, value
- env.halted = halted_lambda.call(target, result)
+ result_lambda = -> { user_callback.call target, value }
+ env.halted = halted_lambda.call(target, result_lambda)
if env.halted
target.send :halted_callback_hook, filter
end
@@ -161,8 +161,9 @@ module ActiveSupport
halted = env.halted
unless halted
- result = user_callback.call target, value
- env.halted = halted_lambda.call(target, result)
+ result_lambda = -> { user_callback.call target, value }
+ env.halted = halted_lambda.call(target, result_lambda)
+
if env.halted
target.send :halted_callback_hook, filter
end
@@ -517,7 +518,8 @@ module ActiveSupport
def initialize(name, config)
@name = name
@config = {
- :scope => [ :kind ]
+ scope: [:kind],
+ terminator: default_terminator
}.merge!(config)
@chain = []
@callbacks = nil
@@ -588,6 +590,17 @@ module ActiveSupport
@callbacks = nil
@chain.delete_if { |c| callback.duplicates?(c) }
end
+
+ def default_terminator
+ Proc.new do |target, result_lambda|
+ terminate = true
+ catch(:abort) do
+ result_lambda.call if result_lambda.is_a?(Proc)
+ terminate = false
+ end
+ terminate
+ end
+ end
end
module ClassMethods