diff options
author | claudiob <claudiob@gmail.com> | 2014-10-16 16:21:24 -0700 |
---|---|---|
committer | claudiob <claudiob@gmail.com> | 2015-01-02 15:31:55 -0800 |
commit | 2386daabe7f8c979b453010dc0de3e1f6bbf859d (patch) | |
tree | 74ab7a4ffc32cda7126e3ce8950d21af0c4c4b90 /activesupport/lib | |
parent | 93dd5028a0cd0363d9f4bfc97d9ce70f0f3e88c8 (diff) | |
download | rails-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.rb | 23 |
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 |