Skip to content
This repository
Browse code

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
Myron Marston authored April 28, 2011
34  activemodel/lib/active_model/observer_array.rb
@@ -48,7 +48,7 @@ def enable(*observers, &block)
48 48
       set_enablement(true, observers, &block)
49 49
     end
50 50
 
51  
-    private
  51
+    protected
52 52
 
53 53
       def observer_class_for(observer)
54 54
         return observer if observer.is_a?(Class)
@@ -61,13 +61,37 @@ def observer_class_for(observer)
61 61
         end
62 62
       end
63 63
 
  64
+      def start_transaction
  65
+        disabled_observer_stack.push(disabled_observers.dup)
  66
+        each_subclass_array do |array|
  67
+          array.start_transaction
  68
+        end
  69
+      end
  70
+
  71
+      def disabled_observer_stack
  72
+        @disabled_observer_stack ||= []
  73
+      end
  74
+
  75
+      def end_transaction
  76
+        @disabled_observers = disabled_observer_stack.pop
  77
+        each_subclass_array do |array|
  78
+          array.end_transaction
  79
+        end
  80
+      end
  81
+
64 82
       def transaction
65  
-        orig_disabled_observers = disabled_observers.dup
  83
+        start_transaction
66 84
 
67 85
         begin
68 86
           yield
69 87
         ensure
70  
-          @disabled_observers = orig_disabled_observers
  88
+          end_transaction
  89
+        end
  90
+      end
  91
+
  92
+      def each_subclass_array
  93
+        model_class.subclasses.each do |subclass|
  94
+          yield self.class.for(subclass)
71 95
         end
72 96
       end
73 97
 
@@ -92,6 +116,10 @@ def set_enablement(enabled, observers)
92 116
               disabled_observers << klass
93 117
             end
94 118
           end
  119
+
  120
+          each_subclass_array do |array|
  121
+            array.set_enablement(enabled, observers)
  122
+          end
95 123
         end
96 124
       end
97 125
   end
5  activemodel/lib/active_model/observing.rb
@@ -70,6 +70,10 @@ def count_observers
70 70
         observer_instances.size
71 71
       end
72 72
 
  73
+      def subclasses
  74
+        @subclasses ||= []
  75
+      end
  76
+
73 77
       protected
74 78
         def instantiate_observer(observer) #:nodoc:
75 79
           # string/symbol
@@ -89,6 +93,7 @@ def instantiate_observer(observer) #:nodoc:
89 93
         # Notify observers when the observed class is subclassed.
90 94
         def inherited(subclass)
91 95
           super
  96
+          subclasses << subclass
92 97
           notify_observers :observed_class_inherited, subclass
93 98
         end
94 99
     end
39  activemodel/test/cases/observer_array_test.rb
@@ -118,5 +118,44 @@ def assert_observer_not_notified(model_class, observer_class)
118 118
       ORM.observers.disable Widget
119 119
     end
120 120
   end
  121
+
  122
+  test "allows #enable at the superclass level to override #disable at the subclass level when called last" do
  123
+    Widget.observers.disable :all
  124
+    ORM.observers.enable :all
  125
+
  126
+    assert_observer_notified Widget, WidgetObserver
  127
+    assert_observer_notified Budget, BudgetObserver
  128
+    assert_observer_notified Widget, AuditTrail
  129
+    assert_observer_notified Budget, AuditTrail
  130
+  end
  131
+
  132
+  test "allows #disable at the superclass level to override #enable at the subclass level when called last" do
  133
+    Budget.observers.enable :audit_trail
  134
+    ORM.observers.disable :audit_trail
  135
+
  136
+    assert_observer_notified     Widget, WidgetObserver
  137
+    assert_observer_notified     Budget, BudgetObserver
  138
+    assert_observer_not_notified Widget, AuditTrail
  139
+    assert_observer_not_notified Budget, AuditTrail
  140
+  end
  141
+
  142
+  test "can use the block form at different levels of the hierarchy" do
  143
+    yielded = false
  144
+    Widget.observers.disable :all
  145
+
  146
+    ORM.observers.enable :all do
  147
+      yielded = true
  148
+      assert_observer_notified Widget, WidgetObserver
  149
+      assert_observer_notified Budget, BudgetObserver
  150
+      assert_observer_notified Widget, AuditTrail
  151
+      assert_observer_notified Budget, AuditTrail
  152
+    end
  153
+
  154
+    assert yielded
  155
+    assert_observer_not_notified Widget, WidgetObserver
  156
+    assert_observer_notified     Budget, BudgetObserver
  157
+    assert_observer_not_notified Widget, AuditTrail
  158
+    assert_observer_notified     Budget, AuditTrail
  159
+  end
121 160
 end
122 161
 

0 notes on commit 05d4653

Please sign in to comment.
Something went wrong with that request. Please try again.