Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AS::Callbacks#define_callbacks: add :terminate_after_callbacks option #4866

Merged
merged 1 commit into from Feb 4, 2012
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions actionpack/lib/abstract_controller/callbacks.rb
Expand Up @@ -8,7 +8,7 @@ module Callbacks
include ActiveSupport::Callbacks

included do
define_callbacks :process_action, :terminator => "response_body"
define_callbacks :process_action, :terminator => "response_body", :skip_after_callbacks_if_terminated => true
end

# Override AbstractController::Base's process_action to run the
Expand Down Expand Up @@ -167,7 +167,6 @@ def _insert_callbacks(callbacks, block)
# for details on the allowed parameters.
def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
_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)
end # end
end # end
Expand All @@ -176,7 +175,6 @@ def #{filter}_filter(*names, &blk)
# for details on the allowed parameters.
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|
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))
end # end
end # end
Expand Down
3 changes: 2 additions & 1 deletion activemodel/lib/active_model/callbacks.rb
Expand Up @@ -88,6 +88,7 @@ def define_model_callbacks(*callbacks)
options = callbacks.extract_options!
options = {
:terminator => "result == false",
:skip_after_callbacks_if_terminated => true,
:scope => [:kind, :name],
:only => [:before, :around, :after]
}.merge(options)
Expand Down Expand Up @@ -124,7 +125,7 @@ def _define_after_model_callback(klass, callback) #:nodoc:
def self.after_#{callback}(*args, &block)
options = args.extract_options!
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)
end
CALLBACK
Expand Down
3 changes: 1 addition & 2 deletions activemodel/lib/active_model/validations/callbacks.rb
Expand Up @@ -23,7 +23,7 @@ module Callbacks

included do
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

module ClassMethods
Expand All @@ -40,7 +40,6 @@ def after_validation(*args, &block)
options = args.extract_options!
options[:prepend] = true
options[:if] = Array(options[:if])
options[:if] << "!halted"
options[:if].unshift("self.validation_context == :#{options[:on]}") if options[:on]
set_callback(:validation, :after, *(args << options), &block)
end
Expand Down
2 changes: 2 additions & 0 deletions activesupport/CHANGELOG.md
@@ -1,5 +1,7 @@
## 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*

* Remove ActiveSupport::TestCase#pending method, use `skip` instead. *Carlos Antonio da Silva*
Expand Down
7 changes: 6 additions & 1 deletion activesupport/lib/active_support/callbacks.rb
Expand Up @@ -169,7 +169,7 @@ def apply(code, key=nil, object=nil)
when :after
<<-RUBY_EVAL
#{code}
if #{@compiled_options}
if #{!chain.config[:skip_after_callbacks_if_terminated] || "!halted"} && #{@compiled_options}
#{@filter}
end
RUBY_EVAL
Expand Down Expand Up @@ -528,6 +528,11 @@ def reset_callbacks(symbol)
# other callbacks are not executed. Defaults to "false", meaning no value
# 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
# 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
Expand Down