aboutsummaryrefslogtreecommitdiffstats
path: root/activemodel
diff options
context:
space:
mode:
authorMyron Marston <myron.marston@gmail.com>2011-04-28 08:27:15 -0700
committerMyron Marston <myron.marston@gmail.com>2011-04-28 08:27:15 -0700
commitfef22157b07f101229d29544d578bfe2cb9fedfe (patch)
tree8053e5b9495da805f4eb12c34885583346914a5e /activemodel
parent9a385394acd6599ff588daad491e9e07ee716091 (diff)
downloadrails-fef22157b07f101229d29544d578bfe2cb9fedfe.tar.gz
rails-fef22157b07f101229d29544d578bfe2cb9fedfe.tar.bz2
rails-fef22157b07f101229d29544d578bfe2cb9fedfe.zip
Fix bug with AM::Observer disablement.
Now that we propagate the enabling/disabling to descendants, we no longer have to check the disabled_observer Set on each superclass of the model class. This was causing a bug when disabling all observers at a superclass level and then enabling an individual observer at a subclass level. Plus the logic is simpler now :).
Diffstat (limited to 'activemodel')
-rw-r--r--activemodel/lib/active_model/observer_array.rb30
-rw-r--r--activemodel/lib/active_model/observing.rb12
-rw-r--r--activemodel/test/cases/observer_array_test.rb10
3 files changed, 27 insertions, 25 deletions
diff --git a/activemodel/lib/active_model/observer_array.rb b/activemodel/lib/active_model/observer_array.rb
index d501215dd6..ab7f86007f 100644
--- a/activemodel/lib/active_model/observer_array.rb
+++ b/activemodel/lib/active_model/observer_array.rb
@@ -4,34 +4,16 @@ module ActiveModel
# Stores the enabled/disabled state of individual observers for
# a particular model classes.
class ObserverArray < Array
- # returns false if:
- # - the ObserverArray for the given model's class has the given observer
- # in its disabled_observers set.
- # - or that is the case at any level of the model's superclass chain.
- def self.observer_enabled?(observer, model)
- klass = model.class
- observer_class = observer.class
-
- loop do
- break unless klass.respond_to?(:observers)
- array = klass.observers
- return false if array.disabled_observers.include?(observer_class)
- klass = klass.superclass
- end
-
- true # observers are enabled by default
- end
-
- def disabled_observers
- @disabled_observers ||= Set.new
- end
-
attr_reader :model_class
def initialize(model_class, *args)
@model_class = model_class
super(*args)
end
+ def disabled_for?(observer)
+ disabled_observers.include?(observer.class)
+ end
+
def disable(*observers, &block)
set_enablement(false, observers, &block)
end
@@ -42,6 +24,10 @@ module ActiveModel
protected
+ def disabled_observers
+ @disabled_observers ||= Set.new
+ end
+
def observer_class_for(observer)
return observer if observer.is_a?(Class)
diff --git a/activemodel/lib/active_model/observing.rb b/activemodel/lib/active_model/observing.rb
index 9ffcda8dd7..c1ac4eb4af 100644
--- a/activemodel/lib/active_model/observing.rb
+++ b/activemodel/lib/active_model/observing.rb
@@ -222,9 +222,9 @@ module ActiveModel
# Send observed_method(object) if the method exists.
def update(observed_method, object) #:nodoc:
- if respond_to?(observed_method) && ObserverArray.observer_enabled?(self, object)
- send(observed_method, object)
- end
+ return unless respond_to?(observed_method)
+ return if disabled_for?(object)
+ send(observed_method, object)
end
# Special method sent by the observed class when it is inherited.
@@ -238,5 +238,11 @@ module ActiveModel
def add_observer!(klass) #:nodoc:
klass.add_observer(self)
end
+
+ def disabled_for?(object)
+ klass = object.class
+ return false unless klass.respond_to?(:observers)
+ klass.observers.disabled_for?(self)
+ end
end
end
diff --git a/activemodel/test/cases/observer_array_test.rb b/activemodel/test/cases/observer_array_test.rb
index 38e4fd59fc..3ede5682b4 100644
--- a/activemodel/test/cases/observer_array_test.rb
+++ b/activemodel/test/cases/observer_array_test.rb
@@ -65,6 +65,16 @@ class ObserverArrayTest < ActiveModel::TestCase
assert_observer_notified Budget, AuditTrail
end
+ test "can enable observers on individual models without affecting those observers on other models" do
+ ORM.observers.disable :all
+ Budget.observers.enable AuditTrail
+
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_not_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
test "can disable observers for the duration of a block" do
yielded = false
ORM.observers.disable :budget_observer do