diff options
-rw-r--r-- | actionpack/lib/action_controller/dispatcher.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/filters.rb | 6 | ||||
-rw-r--r-- | activemodel/lib/active_model/validations.rb | 3 | ||||
-rwxr-xr-x | activerecord/lib/active_record/validations.rb | 3 | ||||
-rw-r--r-- | activesupport/lib/active_support/callbacks.rb | 25 | ||||
-rw-r--r-- | activesupport/test/callbacks_test.rb | 31 |
6 files changed, 54 insertions, 16 deletions
diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 30db7d9f73..99e1f74c0a 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -22,7 +22,7 @@ module ActionController def to_prepare(identifier = nil, &block) @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) - @prepare_dispatch_callbacks.replace_or_append_callback(callback) + @prepare_dispatch_callbacks | callback end # If the block raises, send status code as a last-ditch response. diff --git a/actionpack/lib/action_controller/filters.rb b/actionpack/lib/action_controller/filters.rb index 73721cd1ec..8c97787741 100644 --- a/actionpack/lib/action_controller/filters.rb +++ b/actionpack/lib/action_controller/filters.rb @@ -265,7 +265,7 @@ module ActionController #:nodoc: def skip_filter_in_chain(*filters, &test) filters, conditions = extract_options(filters) filters.each do |filter| - if callback = find_callback(filter) then delete(callback) end + if callback = find(filter) then delete(callback) end end if conditions.empty? update_filter_in_chain(filters, :skip => conditions, &test) end @@ -302,7 +302,7 @@ module ActionController #:nodoc: def find_or_create_filter(filter, filter_type, options = {}) update_filter_in_chain([filter], options) - if found_filter = find_callback(filter) { |f| f.type == filter_type } + if found_filter = find(filter) { |f| f.type == filter_type } found_filter else filter_kind = case @@ -326,7 +326,7 @@ module ActionController #:nodoc: end def update_filter_in_chain(filters, options, &test) - filters.map! { |f| block_given? ? find_callback(f, &test) : find_callback(f) } + filters.map! { |f| block_given? ? find(f, &test) : find(f) } filters.compact! map! do |filter| diff --git a/activemodel/lib/active_model/validations.rb b/activemodel/lib/active_model/validations.rb index 503fb10795..3b7b9050be 100644 --- a/activemodel/lib/active_model/validations.rb +++ b/activemodel/lib/active_model/validations.rb @@ -7,8 +7,7 @@ module ActiveModel %w( validate validate_on_create validate_on_update ).each do |validation_method| base.class_eval <<-"end_eval" def self.#{validation_method}(*methods, &block) - methods = CallbackChain.build(:#{validation_method}, *methods, &block) - self.#{validation_method}_callback_chain.replace(#{validation_method}_callback_chain | methods) + self.#{validation_method}_callback_chain | CallbackChain.build(:#{validation_method}, *methods, &block) end def self.#{validation_method}_callback_chain diff --git a/activerecord/lib/active_record/validations.rb b/activerecord/lib/active_record/validations.rb index 86cda9aa66..7b70f78405 100755 --- a/activerecord/lib/active_record/validations.rb +++ b/activerecord/lib/active_record/validations.rb @@ -285,8 +285,7 @@ module ActiveRecord VALIDATIONS.each do |validation_method| base.class_eval <<-"end_eval" def self.#{validation_method}(*methods, &block) - methods = CallbackChain.build(:#{validation_method}, *methods, &block) - self.#{validation_method}_callback_chain.replace(#{validation_method}_callback_chain | methods) + self.#{validation_method}_callback_chain | CallbackChain.build(:#{validation_method}, *methods, &block) end def self.#{validation_method}_callback_chain diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb index 329cc2fdc7..282b6cbcbc 100644 --- a/activesupport/lib/active_support/callbacks.rb +++ b/activesupport/lib/active_support/callbacks.rb @@ -96,17 +96,26 @@ module ActiveSupport end end - def find_callback(callback, &block) + def |(chain) + if chain.is_a?(Callback) + if found_callback = find(chain) + index = index(found_callback) + self[index] = chain + else + self << chain + end + else + chain.each { |callback| self | callback } + end + self + end + + def find(callback, &block) select { |c| c == callback && (!block_given? || yield(c)) }.first end - def replace_or_append_callback(callback) - if found_callback = find_callback(callback) - index = index(found_callback) - self[index] = callback - else - self << callback - end + def delete(callback) + super(find(callback)) end private diff --git a/activesupport/test/callbacks_test.rb b/activesupport/test/callbacks_test.rb index 3f8cb7f01a..7f71ca2262 100644 --- a/activesupport/test/callbacks_test.rb +++ b/activesupport/test/callbacks_test.rb @@ -96,6 +96,8 @@ class ConditionalCallbackTest < Test::Unit::TestCase end class CallbackTest < Test::Unit::TestCase + include ActiveSupport::Callbacks + def test_eql callback = Callback.new(:before, :save, :identifier => :lifesaver) assert callback.eql?(Callback.new(:before, :save, :identifier => :lifesaver)) @@ -115,3 +117,32 @@ class CallbackTest < Test::Unit::TestCase assert_equal({}, a.options) end end + +class CallbackChainTest < Test::Unit::TestCase + include ActiveSupport::Callbacks + + def setup + @chain = CallbackChain.build(:make, :bacon, :lettuce, :tomato) + end + + def test_build + assert_equal 3, @chain.size + assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method) + end + + def test_find + assert_equal :bacon, @chain.find(:bacon).method + end + + def test_union + assert_equal [:bacon, :lettuce, :tomato], (@chain | Callback.new(:make, :bacon)).map(&:method) + assert_equal [:bacon, :lettuce, :tomato, :turkey], (@chain | CallbackChain.build(:make, :bacon, :lettuce, :tomato, :turkey)).map(&:method) + assert_equal [:bacon, :lettuce, :tomato, :turkey, :mayo], (@chain | Callback.new(:make, :mayo)).map(&:method) + end + + def test_delete + assert_equal [:bacon, :lettuce, :tomato], @chain.map(&:method) + @chain.delete(:bacon) + assert_equal [:lettuce, :tomato], @chain.map(&:method) + end +end |