提交 d217daf6 编写于 作者: C claudiob

Deprecate `false` as the way to halt AS callbacks

After this commit, returning `false` in a callback will display a deprecation
warning to make developers aware of the fact that they need to explicitly
`throw(:abort)` if their intention is to halt a callback chain.

This commit also patches two internal uses of AS::Callbacks (inside
ActiveRecord and ActionDispatch) which sometimes return `false` but whose
returned value is not meaningful for the purpose of execution.

In both cases, the returned value is set to `true`, which does not affect the
execution of the callbacks but prevents unrequested deprecation warnings from
showing up.
上级 2386daab
......@@ -206,7 +206,13 @@ def add_autosave_association_callbacks(reflection)
if reflection.validate? && !method_defined?(validation_method)
method = (collection ? :validate_collection_association : :validate_single_association)
define_non_cyclic_method(validation_method) { send(method, reflection) }
define_non_cyclic_method(validation_method) do
send(method, reflection)
# TODO: remove the following line as soon as the return value of
# callbacks is ignored, that is, returning `false` does not
# display a deprecation warning or halts the callback chain.
true
end
validate validation_method
end
end
......
* Deprecate returning `false` as a way to halt callback chains.
Returning `false` in a callback will display a deprecation warning
explaining that the preferred method to halt a callback chain is to
explicitly `throw(:abort)`.
*claudiob*
* Changes arguments and default value of CallbackChain's :terminator option
Chains of callbacks defined without an explicit `:terminator` option will
......
......@@ -4,6 +4,7 @@
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/kernel/reporting'
require 'active_support/core_ext/kernel/singleton_class'
require 'active_support/core_ext/string/filters'
require 'thread'
module ActiveSupport
......@@ -595,12 +596,23 @@ 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
result = result_lambda.call if result_lambda.is_a?(Proc)
if result == false
display_deprecation_warning_for_false_terminator
else
terminate = false
end
end
terminate
end
end
def display_deprecation_warning_for_false_terminator
ActiveSupport::Deprecation.warn(<<-MSG.squish)
Returning `false` in a callback will not implicitly halt a callback chain in the next release of Rails.
To explicitly halt a callback chain, please use `throw :abort` instead.
MSG
end
end
module ClassMethods
......
......@@ -55,7 +55,13 @@ def self.initialize_i18n(app)
reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
app.reloaders << reloader
ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
ActionDispatch::Reloader.to_prepare do
reloader.execute_if_updated
# TODO: remove the following line as soon as the return value of
# callbacks is ignored, that is, returning `false` does not
# display a deprecation warning or halts the callback chain.
true
end
reloader.execute
@i18n_inited = true
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册