Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "Revert "Handle enabling/disabling observers at different leve…

…ls of the class hierarchy.""

This reverts commit 2a25c58.

I'm going to add another commit that keeps the same behavior of fixes
the problems of leaking memory in development.
  • Loading branch information...
commit 05d4653cef1c1d8d77228de26d55cf6d6a0ce20b 1 parent bf50222
@myronmarston myronmarston authored
View
34 activemodel/lib/active_model/observer_array.rb
@@ -48,7 +48,7 @@ def enable(*observers, &block)
set_enablement(true, observers, &block)
end
- private
+ protected
def observer_class_for(observer)
return observer if observer.is_a?(Class)
@@ -61,13 +61,37 @@ def observer_class_for(observer)
end
end
+ def start_transaction
+ disabled_observer_stack.push(disabled_observers.dup)
+ each_subclass_array do |array|
+ array.start_transaction
+ end
+ end
+
+ def disabled_observer_stack
+ @disabled_observer_stack ||= []
+ end
+
+ def end_transaction
+ @disabled_observers = disabled_observer_stack.pop
+ each_subclass_array do |array|
+ array.end_transaction
+ end
+ end
+
def transaction
- orig_disabled_observers = disabled_observers.dup
+ start_transaction
begin
yield
ensure
- @disabled_observers = orig_disabled_observers
+ end_transaction
+ end
+ end
+
+ def each_subclass_array
+ model_class.subclasses.each do |subclass|
+ yield self.class.for(subclass)
end
end
@@ -92,6 +116,10 @@ def set_enablement(enabled, observers)
disabled_observers << klass
end
end
+
+ each_subclass_array do |array|
+ array.set_enablement(enabled, observers)
+ end
end
end
end
View
5 activemodel/lib/active_model/observing.rb
@@ -70,6 +70,10 @@ def count_observers
observer_instances.size
end
+ def subclasses
+ @subclasses ||= []
+ end
+
protected
def instantiate_observer(observer) #:nodoc:
# string/symbol
@@ -89,6 +93,7 @@ def instantiate_observer(observer) #:nodoc:
# Notify observers when the observed class is subclassed.
def inherited(subclass)
super
+ subclasses << subclass
notify_observers :observed_class_inherited, subclass
end
end
View
39 activemodel/test/cases/observer_array_test.rb
@@ -118,5 +118,44 @@ def assert_observer_not_notified(model_class, observer_class)
ORM.observers.disable Widget
end
end
+
+ test "allows #enable at the superclass level to override #disable at the subclass level when called last" do
+ Widget.observers.disable :all
+ ORM.observers.enable :all
+
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ test "allows #disable at the superclass level to override #enable at the subclass level when called last" do
+ Budget.observers.enable :audit_trail
+ ORM.observers.disable :audit_trail
+
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_not_notified Budget, AuditTrail
+ end
+
+ test "can use the block form at different levels of the hierarchy" do
+ yielded = false
+ Widget.observers.disable :all
+
+ ORM.observers.enable :all do
+ yielded = true
+ assert_observer_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
+
+ assert yielded
+ assert_observer_not_notified Widget, WidgetObserver
+ assert_observer_notified Budget, BudgetObserver
+ assert_observer_not_notified Widget, AuditTrail
+ assert_observer_notified Budget, AuditTrail
+ end
end
Please sign in to comment.
Something went wrong with that request. Please try again.