diff --git a/activerecord/lib/active_record/associations/association_collection.rb b/activerecord/lib/active_record/associations/association_collection.rb index b2b3a9789c..1ceb0dbf96 100644 --- a/activerecord/lib/active_record/associations/association_collection.rb +++ b/activerecord/lib/active_record/associations/association_collection.rb @@ -485,7 +485,14 @@ module ActiveRecord def callback(method, record) callbacks_for(method).each do |callback| - ActiveSupport::DeprecatedCallbacks::Callback.new(method, callback, record).call(@owner, record) + case callback + when Symbol + @owner.send(callback, record) + when Proc + callback.call(@owner, record) + else + callback.send(method, @owner, record) + end end end diff --git a/activerecord/lib/active_record/callbacks.rb b/activerecord/lib/active_record/callbacks.rb index e1d772bd95..e2a8f03c8f 100644 --- a/activerecord/lib/active_record/callbacks.rb +++ b/activerecord/lib/active_record/callbacks.rb @@ -274,7 +274,7 @@ module ActiveRecord def deprecated_callback_method(symbol) #:nodoc: if respond_to?(symbol) - ActiveSupport::Deprecation.warn("Base##{symbol} has been deprecated, please use Base.#{symbol} :method instead") + ActiveSupport::Deprecation.warn("Overwriting #{symbol} in your models has been deprecated, please use Base##{symbol} :method_name instead") send(symbol) end end diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index e8a2a72735..12c1f23763 100644 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -17,8 +17,6 @@ module ActiveRecord module Validations extend ActiveSupport::Concern - - include ActiveSupport::DeprecatedCallbacks include ActiveModel::Validations included do diff --git a/activesupport/lib/active_support.rb b/activesupport/lib/active_support.rb index 8215cfaf0d..3463000529 100644 --- a/activesupport/lib/active_support.rb +++ b/activesupport/lib/active_support.rb @@ -50,7 +50,6 @@ module ActiveSupport autoload :Callbacks autoload :Concern autoload :Configurable - autoload :DeprecatedCallbacks autoload :Deprecation autoload :Gzip autoload :Inflector diff --git a/activesupport/lib/active_support/deprecated_callbacks.rb b/activesupport/lib/active_support/deprecated_callbacks.rb deleted file mode 100644 index f56fef0b6d..0000000000 --- a/activesupport/lib/active_support/deprecated_callbacks.rb +++ /dev/null @@ -1,284 +0,0 @@ -require 'active_support/core_ext/array/extract_options' -require 'active_support/core_ext/array/wrap' - -module ActiveSupport - # Callbacks are hooks into the lifecycle of an object that allow you to trigger logic - # before or after an alteration of the object state. - # - # Mixing in this module allows you to define callbacks in your class. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # end - # - # class ConfigStorage < Storage - # before_save :saving_message - # def saving_message - # puts "saving..." - # end - # - # after_save do |object| - # puts "saved" - # end - # - # def save - # run_callbacks(:before_save) - # puts "- save" - # run_callbacks(:after_save) - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # saving... - # - save - # saved - # - # Callbacks from parent classes are inherited. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # - # before_save :prepare - # def prepare - # puts "preparing save" - # end - # end - # - # class ConfigStorage < Storage - # before_save :saving_message - # def saving_message - # puts "saving..." - # end - # - # after_save do |object| - # puts "saved" - # end - # - # def save - # run_callbacks(:before_save) - # puts "- save" - # run_callbacks(:after_save) - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # preparing save - # saving... - # - save - # saved - module DeprecatedCallbacks - class CallbackChain < Array - def self.build(kind, *methods, &block) - methods, options = extract_options(*methods, &block) - methods.map! { |method| Callback.new(kind, method, options) } - new(methods) - end - - def run(object, options = {}, &terminator) - enumerator = options[:enumerator] || :each - - unless block_given? - send(enumerator) { |callback| callback.call(object) } - else - send(enumerator) do |callback| - result = callback.call(object) - break result if terminator.call(result, object) - end - end - end - - # TODO: Decompose into more Array like behavior - def replace_or_append!(chain) - if index = index(chain) - self[index] = chain - else - self << chain - end - self - end - - def find(callback, &block) - select { |c| c == callback && (!block_given? || yield(c)) }.first - end - - def delete(callback) - super(callback.is_a?(Callback) ? callback : find(callback)) - end - - private - def self.extract_options(*methods, &block) - methods.flatten! - options = methods.extract_options! - methods << block if block_given? - return methods, options - end - - def extract_options(*methods, &block) - self.class.extract_options(*methods, &block) - end - end - - class Callback - attr_reader :kind, :method, :identifier, :options - - def initialize(kind, method, options = {}) - @kind = kind - @method = method - @identifier = options[:identifier] - @options = options - end - - def ==(other) - case other - when Callback - (self.identifier && self.identifier == other.identifier) || self.method == other.method - else - (self.identifier && self.identifier == other) || self.method == other - end - end - - def eql?(other) - self == other - end - - def dup - self.class.new(@kind, @method, @options.dup) - end - - def hash - if @identifier - @identifier.hash - else - @method.hash - end - end - - def call(*args, &block) - evaluate_method(method, *args, &block) if should_run_callback?(*args) - rescue LocalJumpError - raise ArgumentError, - "Cannot yield from a Proc type filter. The Proc must take two " + - "arguments and execute #call on the second argument." - end - - private - def evaluate_method(method, *args, &block) - case method - when Symbol - object = args.shift - object.send(method, *args, &block) - when String - eval(method, args.first.instance_eval { binding }) - when Proc, Method - method.call(*args, &block) - else - if method.respond_to?(kind) - method.send(kind, *args, &block) - else - raise ArgumentError, - "Callbacks must be a symbol denoting the method to call, a string to be evaluated, " + - "a block to be invoked, or an object responding to the callback method." - end - end - end - - def should_run_callback?(*args) - Array.wrap(options[:if]).flatten.compact.all? { |a| evaluate_method(a, *args) } && - !Array.wrap(options[:unless]).flatten.compact.any? { |a| evaluate_method(a, *args) } - end - end - - def self.included(base) - base.extend ClassMethods - end - - module ClassMethods - def define_callbacks(*callbacks) - ActiveSupport::Deprecation.warn('ActiveSupport::DeprecatedCallbacks has been deprecated in favor of ActiveSupport::Callbacks', caller) - - callbacks.each do |callback| - class_eval <<-"end_eval", __FILE__, __LINE__ + 1 - def self.#{callback}(*methods, &block) # def self.before_save(*methods, &block) - callbacks = CallbackChain.build(:#{callback}, *methods, &block) # callbacks = CallbackChain.build(:before_save, *methods, &block) - @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new - @#{callback}_callbacks.concat callbacks # @before_save_callbacks.concat callbacks - end # end - # - def self.#{callback}_callback_chain # def self.before_save_callback_chain - @#{callback}_callbacks ||= CallbackChain.new # @before_save_callbacks ||= CallbackChain.new - # - if superclass.respond_to?(:#{callback}_callback_chain) # if superclass.respond_to?(:before_save_callback_chain) - CallbackChain.new( # CallbackChain.new( - superclass.#{callback}_callback_chain + # superclass.before_save_callback_chain + - @#{callback}_callbacks # @before_save_callbacks - ) # ) - else # else - @#{callback}_callbacks # @before_save_callbacks - end # end - end # end - end_eval - end - end - end - - # Runs all the callbacks defined for the given options. - # - # If a block is given it will be called after each callback receiving as arguments: - # - # * the result from the callback - # * the object which has the callback - # - # If the result from the block evaluates to +true+, the callback chain is stopped. - # - # Example: - # class Storage - # include ActiveSupport::DeprecatedCallbacks - # - # define_callbacks :before_save, :after_save - # end - # - # class ConfigStorage < Storage - # before_save :pass - # before_save :pass - # before_save :stop - # before_save :pass - # - # def pass - # puts "pass" - # end - # - # def stop - # puts "stop" - # return false - # end - # - # def save - # result = run_callbacks(:before_save) { |result, object| result == false } - # puts "- save" if result - # end - # end - # - # config = ConfigStorage.new - # config.save - # - # Output: - # pass - # pass - # stop - def run_callbacks(kind, options = {}, &block) - self.class.send("#{kind}_callback_chain").run(self, options, &block) - end - end -end