public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Run callbacks from object's metaclass [#575 state:resolved]
josh (author)
Tue Jul 15 19:55:28 -0700 2008
commit  be078ee162fcae883a5621a30929879cd783a238
tree    6f6b6f31fef96c98771aff9f7a9da5cc0836da51
parent  f4f6e57e8c2a446a4a600576f0caf0fb8921ba13
...
1
2
 
 
3
4
5
...
1
2
3
4
5
6
7
0
@@ -1,5 +1,7 @@
0
 *Edge*
0
 
0
+* Run callbacks from object's metaclass [Josh Peek]
0
+
0
 * Add Array#in_groups which splits or iterates over the array in specified number of groups. #579. [Adrian Mugnolo] Example:
0
   
0
   a = (1..10).to_a
...
269
270
271
272
 
 
 
 
 
 
 
 
 
273
274
275
...
269
270
271
 
272
273
274
275
276
277
278
279
280
281
282
283
0
@@ -269,7 +269,15 @@ module ActiveSupport
0
     #   pass
0
     #   stop
0
     def run_callbacks(kind, options = {}, &block)
0
-      self.class.send("#{kind}_callback_chain").run(self, options, &block)
0
+      callback_chain_method = "#{kind}_callback_chain"
0
+
0
+      # Meta class inherits Class so we don't have to merge it in 1.9
0
+      if RUBY_VERSION >= '1.9'
0
+        metaclass.send(callback_chain_method).run(self, options, &block)
0
+      else
0
+        callbacks = self.class.send(callback_chain_method) | metaclass.send(callback_chain_method)
0
+        callbacks.run(self, options, &block)
0
+      end
0
     end
0
   end
0
 end
...
84
85
86
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
87
88
89
...
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
0
@@ -84,6 +84,30 @@ class CallbacksTest < Test::Unit::TestCase
0
   end
0
 end
0
 
0
+class MetaclassCallbacksTest < Test::Unit::TestCase
0
+  module ModuleWithCallbacks
0
+    def self.extended(object)
0
+      object.metaclass.before_save :raise_metaclass_callback_called
0
+    end
0
+
0
+    def module_callback_called?
0
+      @module_callback_called ||= false
0
+    end
0
+
0
+    def raise_metaclass_callback_called
0
+      @module_callback_called = true
0
+    end
0
+  end
0
+
0
+  def test_metaclass_callbacks
0
+    person = Person.new
0
+    person.extend(ModuleWithCallbacks)
0
+    assert !person.module_callback_called?
0
+    person.save
0
+    assert person.module_callback_called?
0
+  end
0
+end
0
+
0
 class ConditionalCallbackTest < Test::Unit::TestCase
0
   def test_save_conditional_person
0
     person = ConditionalPerson.new

Comments