Skip to content
This repository has been archived by the owner on May 11, 2022. It is now read-only.

Commit

Permalink
Merge branch 'master' of github.com:patmaddox/no-peeping-toms
Browse files Browse the repository at this point in the history
  • Loading branch information
Pat Maddox committed Jul 27, 2012
2 parents eb2815b + 564a9fd commit ef9d248
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 23 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -3,3 +3,4 @@
Gemfile.lock
pkg/*
spec/debug.log
.*.sw?
3 changes: 3 additions & 0 deletions History.rdoc
@@ -1,3 +1,6 @@
=== Version 2.0.2 / 2012-07-26
* Fix deprecation warning

=== Version 2.0.1 / 2011-02-16
* Supports current Rails 3.x release. No longer supports Rails 2.

Expand Down
46 changes: 25 additions & 21 deletions lib/no_peeping_toms.rb
Expand Up @@ -45,32 +45,36 @@ def observer_enabled?(observer)
end
end

module InstanceMethods
# Overrides ActiveRecord#define_callbacks so that observers are only called
# when enabled.
#
# This is a bit yuck being a protected method, but appears to be the cleanest
# way so far
def define_callbacks_with_enabled_check(klass)
observer = self
observer_name = observer.class.name.underscore.gsub('/', '__')
# Overrides ActiveRecord#define_callbacks so that observers are only called
# when enabled.
#
# This is a bit yuck being a protected method, but appears to be the cleanest
# way so far
def define_callbacks_with_enabled_check(klass)
observer = self
observer_name = observer.class.name.underscore.gsub('/', '__')

ActiveRecord::Callbacks::CALLBACKS.each do |callback|
next unless respond_to?(callback)
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
unless klass.respond_to?(callback_meth)
klass.send(:define_method, callback_meth) do
observer.send(callback, self) if observer.observer_enabled?
end
klass.send(callback, callback_meth)
ActiveRecord::Callbacks::CALLBACKS.each do |callback|
next unless respond_to?(callback)
callback_meth = :"_notify_#{observer_name}_for_#{callback}"
unless klass.respond_to?(callback_meth)
klass.send(:define_method, callback_meth) do
observer.send(callback, self) if observer.observer_enabled?
end
klass.send(callback, callback_meth)
end
end
end

# Determines whether this observer should be run
def observer_enabled?
self.class.observer_enabled?(self)
end
# Enables interception of custom observer notifications, i.e.
# notify_observers(:custom_notification)
def update(*args, &block)
super if observer_enabled?
end

# Determines whether this observer should be run
def observer_enabled?
self.class.observer_enabled?(self)
end
end

Expand Down
36 changes: 34 additions & 2 deletions spec/no_peeping_toms_spec.rb
Expand Up @@ -3,7 +3,22 @@
module NoPeepingTomsSpec
class Person < ActiveRecord::Base; end
class SpecialPerson < Person; end

class HungryPerson < Person
def eat_dinner!
notify_observers(:ate_dinner)
end
end

class DinnerObserver < ActiveRecord::Observer
observe Person
cattr_accessor :called

def ate_dinner(person)
self.class.called ||= 0
self.class.called += 1
end
end

class PersonObserver < ActiveRecord::Observer
cattr_accessor :called

Expand All @@ -12,7 +27,7 @@ def before_create(person)
self.class.called += 1
end
end

class AnotherObserver < ActiveRecord::Observer
observe Person
cattr_accessor :called
Expand All @@ -26,6 +41,7 @@ def before_create(person)
# Register the observers with the host app
PersonObserver.instance
AnotherObserver.instance
DinnerObserver.instance

describe NoPeepingToms, "configuration" do
it "enables observers by default" do
Expand Down Expand Up @@ -82,6 +98,22 @@ def before_create(person)
AnotherObserver.called.should be_true
end

it "should not call observers with custom notifications if they are disabled" do
DinnerObserver.called = 0
lambda {
HungryPerson.new.eat_dinner!
}.should_not change(DinnerObserver, :called)
end

it "should call observers with custom notifications if they are enabled" do
DinnerObserver.called = 0
ActiveRecord::Observer.with_observers(NoPeepingTomsSpec::DinnerObserver) do
lambda {
HungryPerson.new.eat_dinner!
}.should change(DinnerObserver, :called).by(1)
end
end

it "should ensure peeping toms are reset after raised exception" do
lambda {
ActiveRecord::Observer.with_observers(NoPeepingTomsSpec::PersonObserver) do
Expand Down

0 comments on commit ef9d248

Please sign in to comment.