提交 b41ef0a4 编写于 作者: J José Valim

Merge pull request #4866 from bogdan/terminate_after_callbacks

AS::Callbacks#define_callbacks: add :terminate_after_callbacks option
...@@ -8,7 +8,7 @@ module Callbacks ...@@ -8,7 +8,7 @@ module Callbacks
include ActiveSupport::Callbacks include ActiveSupport::Callbacks
included do included do
define_callbacks :process_action, :terminator => "response_body" define_callbacks :process_action, :terminator => "response_body", :skip_after_callbacks_if_terminated => true
end end
# Override AbstractController::Base's process_action to run the # Override AbstractController::Base's process_action to run the
...@@ -165,7 +165,6 @@ def _insert_callbacks(callbacks, block) ...@@ -165,7 +165,6 @@ def _insert_callbacks(callbacks, block)
# for details on the allowed parameters. # for details on the allowed parameters.
def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk) def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options| _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
options[:if] = (Array(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array(options[:if]) << "!halted") if false
set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before, name, options) set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before, name, options)
end # end end # end
end # end end # end
...@@ -174,7 +173,6 @@ def #{filter}_filter(*names, &blk) ...@@ -174,7 +173,6 @@ def #{filter}_filter(*names, &blk)
# for details on the allowed parameters. # for details on the allowed parameters.
def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk) def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
_insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options| _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
options[:if] = (Array(options[:if]) << "!halted") if #{filter == :after} # options[:if] = (Array(options[:if]) << "!halted") if false
set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true)) set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
end # end end # end
end # end end # end
......
...@@ -88,6 +88,7 @@ def define_model_callbacks(*callbacks) ...@@ -88,6 +88,7 @@ def define_model_callbacks(*callbacks)
options = callbacks.extract_options! options = callbacks.extract_options!
options = { options = {
:terminator => "result == false", :terminator => "result == false",
:skip_after_callbacks_if_terminated => true,
:scope => [:kind, :name], :scope => [:kind, :name],
:only => [:before, :around, :after] :only => [:before, :around, :after]
}.merge(options) }.merge(options)
...@@ -124,7 +125,7 @@ def _define_after_model_callback(klass, callback) #:nodoc: ...@@ -124,7 +125,7 @@ def _define_after_model_callback(klass, callback) #:nodoc:
def self.after_#{callback}(*args, &block) def self.after_#{callback}(*args, &block)
options = args.extract_options! options = args.extract_options!
options[:prepend] = true options[:prepend] = true
options[:if] = Array(options[:if]) << "!halted && value != false" options[:if] = Array(options[:if]) << "value != false"
set_callback(:#{callback}, :after, *(args << options), &block) set_callback(:#{callback}, :after, *(args << options), &block)
end end
CALLBACK CALLBACK
......
...@@ -23,7 +23,7 @@ module Callbacks ...@@ -23,7 +23,7 @@ module Callbacks
included do included do
include ActiveSupport::Callbacks include ActiveSupport::Callbacks
define_callbacks :validation, :terminator => "result == false", :scope => [:kind, :name] define_callbacks :validation, :terminator => "result == false", :skip_after_callbacks_if_terminated => true, :scope => [:kind, :name]
end end
module ClassMethods module ClassMethods
...@@ -40,7 +40,6 @@ def after_validation(*args, &block) ...@@ -40,7 +40,6 @@ def after_validation(*args, &block)
options = args.extract_options! options = args.extract_options!
options[:prepend] = true options[:prepend] = true
options[:if] = Array(options[:if]) options[:if] = Array(options[:if])
options[:if] << "!halted"
options[:if].unshift("self.validation_context == :#{options[:on]}") if options[:on] options[:if].unshift("self.validation_context == :#{options[:on]}") if options[:on]
set_callback(:validation, :after, *(args << options), &block) set_callback(:validation, :after, *(args << options), &block)
end end
......
## Rails 4.0.0 (unreleased) ## ## Rails 4.0.0 (unreleased) ##
* `AS::Callbacks#define_callbacks`: add `:skip_after_callbacks_if_terminated` option.
* Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it. *Carlos Antonio da Silva* * Add html_escape_once to ERB::Util, and delegate escape_once tag helper to it. *Carlos Antonio da Silva*
* Remove ActiveSupport::TestCase#pending method, use `skip` instead. *Carlos Antonio da Silva* * Remove ActiveSupport::TestCase#pending method, use `skip` instead. *Carlos Antonio da Silva*
......
...@@ -169,7 +169,7 @@ def apply(code, key=nil, object=nil) ...@@ -169,7 +169,7 @@ def apply(code, key=nil, object=nil)
when :after when :after
<<-RUBY_EVAL <<-RUBY_EVAL
#{code} #{code}
if #{@compiled_options} if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}
#{@filter} #{@filter}
end end
RUBY_EVAL RUBY_EVAL
...@@ -528,6 +528,11 @@ def reset_callbacks(symbol) ...@@ -528,6 +528,11 @@ def reset_callbacks(symbol)
# other callbacks are not executed. Defaults to "false", meaning no value # other callbacks are not executed. Defaults to "false", meaning no value
# halts the chain. # halts the chain.
# #
# * <tt>:skip_after_callbacks_if_terminated</tt> - Determines if after callbacks should be terminated
# by the <tt>:terminator</tt> option. By default after callbacks executed no matter
# if callback chain was terminated or not.
# Option makes sence only when <tt>:terminator</tt> option is specified.
#
# * <tt>:rescuable</tt> - By default, after filters are not executed if # * <tt>:rescuable</tt> - By default, after filters are not executed if
# the given block or a before filter raises an error. By setting this option # the given block or a before filter raises an error. By setting this option
# to <tt>true</tt> exception raised by given block is stored and after # to <tt>true</tt> exception raised by given block is stored and after
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册