Skip to content

Commit

Permalink
Make observers define #after_find in the model only if needed.
Browse files Browse the repository at this point in the history
[#676 state:resolved]
Signed-off-by: Michael Koziarski <michael@koziarski.com>
  • Loading branch information
oggy authored and tarmo committed Aug 24, 2008
1 parent 8d61ead commit 473d8d0
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
3 changes: 3 additions & 0 deletions activerecord/lib/active_record/observer.rb
Expand Up @@ -189,6 +189,9 @@ def observed_subclasses

def add_observer!(klass)
klass.add_observer(self)
if respond_to?(:after_find) && !klass.method_defined?(:after_find)
klass.class_eval 'def after_find() end'
end
end
end
end
32 changes: 30 additions & 2 deletions activerecord/test/cases/lifecycle_test.rb
Expand Up @@ -143,12 +143,12 @@ def test_observing_subclasses
assert_equal developer.name, multi_observer.record.name
end

def test_after_find_cannot_be_observed_when_its_not_defined_on_the_model
def test_after_find_can_be_observed_when_its_not_defined_on_the_model
observer = MinimalisticObserver.instance
assert_equal Minimalistic, MinimalisticObserver.observed_class

minimalistic = Minimalistic.find(1)
assert_nil observer.minimalistic
assert_equal minimalistic, observer.minimalistic
end

def test_after_find_can_be_observed_when_its_defined_on_the_model
Expand All @@ -159,6 +159,34 @@ def test_after_find_can_be_observed_when_its_defined_on_the_model
assert_equal topic, observer.topic
end

def test_after_find_is_not_created_if_its_not_used
# use a fresh class so an observer can't have defined an
# after_find on it
model_class = Class.new(ActiveRecord::Base)
observer_class = Class.new(ActiveRecord::Observer)
observer_class.observe(model_class)

observer = observer_class.instance

assert !model_class.method_defined?(:after_find)
end

def test_after_find_is_not_clobbered_if_it_already_exists
# use a fresh observer class so we can instantiate it (Observer is
# a Singleton)
model_class = Class.new(ActiveRecord::Base) do
def after_find; end
end
original_method = model_class.instance_method(:after_find)
observer_class = Class.new(ActiveRecord::Observer) do
def after_find; end
end
observer_class.observe(model_class)

observer = observer_class.instance
assert_equal original_method, model_class.instance_method(:after_find)
end

def test_invalid_observer
assert_raise(ArgumentError) { Topic.observers = Object.new; Topic.instantiate_observers }
end
Expand Down

0 comments on commit 473d8d0

Please sign in to comment.