diff options
Diffstat (limited to 'activesupport/lib/active_support/callbacks.rb')
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 94 |
1 files changed, 30 insertions, 64 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index c4cfc11372..2cffa342ef 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -94,6 +94,15 @@ module ActiveSupport def halted_callback_hook(filter) end + module Conditionals # :nodoc: + class Value + def initialize(&block) + @block = block + end + def call(target, value); @block.call(value); end + end + end + module Filters Environment = Struct.new(:target, :halted, :value, :run_block) @@ -146,7 +155,7 @@ module ActiveSupport value = env.value halted = env.halted - if !halted + unless halted result = user_callback.call target, value env.halted = halted_lambda.call(target, result) if env.halted @@ -217,7 +226,7 @@ module ActiveSupport def self.halting(next_callback, user_callback) lambda { |env| env = next_callback.call env - if !env.halted + unless env.halted user_callback.call env.target, env.value end env @@ -284,7 +293,7 @@ module ActiveSupport target = env.target value = env.value - if !env.halted + unless env.halted user_callback.call(target, value) { env = next_callback.call env env.value @@ -330,7 +339,7 @@ module ActiveSupport new chain.name, filter, kind, options, chain.config end - attr_accessor :kind, :options, :name + attr_accessor :kind, :name attr_reader :chain_config def initialize(name, filter, kind, options, chain_config) @@ -338,39 +347,24 @@ module ActiveSupport @name = name @kind = kind @filter = filter - @options = options @key = compute_identifier filter - - deprecate_per_key_option(options) - normalize_options!(options) + @if = Array(options[:if]) + @unless = Array(options[:unless]) end def filter; @key; end def raw_filter; @filter; end - def deprecate_per_key_option(options) - if options[:per_key] - raise NotImplementedError, ":per_key option is no longer supported. Use generic :if and :unless options instead." - end - end - def merge(chain, new_options) - _options = { - :if => @options[:if].dup, - :unless => @options[:unless].dup + options = { + :if => @if.dup, + :unless => @unless.dup } - deprecate_per_key_option new_options - - _options[:if].concat Array(new_options.fetch(:unless, [])) - _options[:unless].concat Array(new_options.fetch(:if, [])) + options[:if].concat Array(new_options.fetch(:unless, [])) + options[:unless].concat Array(new_options.fetch(:if, [])) - self.class.build chain, @filter, @kind, _options - end - - def normalize_options!(options) - options[:if] = Array(options[:if]) - options[:unless] = Array(options[:unless]) + self.class.build chain, @filter, @kind, options end def matches?(_kind, _filter) @@ -418,8 +412,8 @@ module ActiveSupport # the same after this point: # # Symbols:: Already methods. - # Strings:: class_eval'ed into methods. - # Procs:: define_method'ed into methods. + # Strings:: class_eval'd into methods. + # Procs:: using define_method compiled into methods. # Objects:: # a method is created that calls the before_foo method # on the object. @@ -430,6 +424,7 @@ module ActiveSupport when String l = eval "lambda { |value| #{filter} }" lambda { |target, value| target.instance_exec(value, &l) } + when Conditionals::Value then filter when ::Proc if filter.arity > 1 return lambda { |target, _, &block| @@ -463,37 +458,8 @@ module ActiveSupport end def conditions_lambdas - conditions = [] - - unless options[:if].empty? - lambdas = Array(options[:if]).map { |c| make_lambda c } - conditions.concat lambdas - end - - unless options[:unless].empty? - lambdas = Array(options[:unless]).map { |c| make_lambda c } - conditions.concat lambdas.map { |l| invert_lambda l } - end - conditions - end - - def _normalize_legacy_filter(kind, filter) - if !filter.respond_to?(kind) && filter.respond_to?(:filter) - message = "Filter object with #filter method is deprecated. Define method corresponding " \ - "to filter type (#before, #after or #around)." - ActiveSupport::Deprecation.warn message - filter.singleton_class.class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 - def #{kind}(context, &block) filter(context, &block) end - RUBY_EVAL - elsif filter.respond_to?(:before) && filter.respond_to?(:after) && kind == :around && !filter.respond_to?(:around) - message = "Filter object with #before and #after methods is deprecated. Define #around method instead." - ActiveSupport::Deprecation.warn message - def filter.around(context) - should_continue = before(context) - yield if should_continue - after(context) - end - end + @if.map { |c| make_lambda c } + + @unless.map { |c| invert_lambda make_lambda c } end end @@ -581,7 +547,7 @@ module ActiveSupport module ClassMethods - def normalize_callback_params(name, filters, block) # :nodoc: + def normalize_callback_params(filters, block) # :nodoc: type = CALLBACK_FILTER_TYPES.include?(filters.first) ? filters.shift : :before options = filters.last.is_a?(Hash) ? filters.pop : {} filters.unshift(block) if block @@ -633,7 +599,7 @@ module ActiveSupport # * <tt>:prepend</tt> - If +true+, the callback will be prepended to the # existing chain rather than appended. def set_callback(name, *filter_list, &block) - type, filters, options = normalize_callback_params(name, filter_list, block) + type, filters, options = normalize_callback_params(filter_list, block) self_chain = get_callbacks name mapped = filters.map do |filter| Callback.build(self_chain, filter, type, options) @@ -653,7 +619,7 @@ module ActiveSupport # skip_callback :validate, :before, :check_membership, if: -> { self.age > 18 } # end def skip_callback(name, *filter_list, &block) - type, filters, options = normalize_callback_params(name, filter_list, block) + type, filters, options = normalize_callback_params(filter_list, block) __update_callbacks(name) do |target, chain| filters.each do |filter| @@ -692,7 +658,7 @@ module ActiveSupport # # * <tt>:terminator</tt> - Determines when a before filter will halt the # callback chain, preventing following callbacks from being called and - # the event from being triggered. This is a string to be eval'ed. The + # the event from being triggered. This is a string to be eval'd. The # result of the callback is available in the +result+ variable. # # define_callbacks :validate, terminator: 'result == false' |