aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activesupport/lib/active_support/callbacks.rb2
-rw-r--r--activesupport/test/callback_inheritance_test.rb30
2 files changed, 31 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/callbacks.rb b/activesupport/lib/active_support/callbacks.rb
index a7a7836f03..418102352f 100644
--- a/activesupport/lib/active_support/callbacks.rb
+++ b/activesupport/lib/active_support/callbacks.rb
@@ -416,7 +416,7 @@ module ActiveSupport
options = filters.last.is_a?(Hash) ? filters.pop : {}
filters.unshift(block) if block
- ([self] + ActiveSupport::DescendantsTracker.descendants(self)).each do |target|
+ ([self] + ActiveSupport::DescendantsTracker.descendants(self)).reverse.each do |target|
chain = target.send("_#{name}_callbacks")
yield target, chain.dup, type, filters, options
target.__define_runner(name)
diff --git a/activesupport/test/callback_inheritance_test.rb b/activesupport/test/callback_inheritance_test.rb
index 71249050fc..d569cbb4fb 100644
--- a/activesupport/test/callback_inheritance_test.rb
+++ b/activesupport/test/callback_inheritance_test.rb
@@ -82,6 +82,30 @@ class EmptyChild < EmptyParent
end
end
+class CountingParent
+ include ActiveSupport::Callbacks
+
+ attr_reader :count
+
+ define_callbacks :dispatch
+
+ def initialize
+ @count = 0
+ end
+
+ def count!
+ @count += 1
+ end
+
+ def dispatch
+ run_callbacks(:dispatch)
+ self
+ end
+end
+
+class CountingChild < CountingParent
+end
+
class BasicCallbacksTest < Test::Unit::TestCase
def setup
@index = GrandParent.new("index").dispatch
@@ -147,4 +171,10 @@ class DynamicInheritedCallbacks < Test::Unit::TestCase
child = EmptyChild.new.dispatch
assert child.performed?
end
+
+ def test_callbacks_should_be_performed_once_in_child_class
+ CountingParent.set_callback(:dispatch, :before) { count! }
+ child = CountingChild.new.dispatch
+ assert_equal 1, child.count
+ end
end