Skip to content

Commit

Permalink
Prevent callbacks in child classes from being executed more than once.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rolf Timmermans authored and josevalim committed Mar 12, 2011
1 parent 46f6a2e commit 1a3fe8c
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
2 changes: 1 addition & 1 deletion activesupport/lib/active_support/callbacks.rb
Original file line number Diff line number Diff line change
Expand Up @@ -416,7 +416,7 @@ def __update_callbacks(name, filters = [], block = nil) #:nodoc:
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)
Expand Down
30 changes: 30 additions & 0 deletions activesupport/test/callback_inheritance_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,30 @@ def do_nothing
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
Expand Down Expand Up @@ -147,4 +171,10 @@ def test_callbacks_looks_to_the_superclass_before_running
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

0 comments on commit 1a3fe8c

Please sign in to comment.