public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
Allow for the dirty tracking to work with the aliased name of aliased 
attributes.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#812 state:committed]
rich (author)
Fri Aug 15 18:49:22 -0700 2008
NZKoz (committer)
Sat Sep 13 02:41:14 -0700 2008
commit  113de01eaf48f64d2adf9f34d699e51619af616f
tree    8d24c2f6fb226604a609773d5a5a2e14897baf38
parent  fcf31cb7521ba7de0aae972ac2ddfc80e3e7dfce
...
34
35
36
 
 
37
38
 
39
40
41
...
44
45
46
 
 
47
48
49
...
161
162
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
165
...
34
35
36
37
38
39
 
40
41
42
43
...
46
47
48
49
50
51
52
53
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
0
@@ -34,8 +34,10 @@ module ActiveRecord
0
   #   person.name << 'by'
0
   #   person.name_change    # => ['uncle bob', 'uncle bobby']
0
   module Dirty
0
+    DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was']
0
+
0
     def self.included(base)
0
-      base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was'
0
+      base.attribute_method_suffix *DIRTY_SUFFIXES
0
       base.alias_method_chain :write_attribute, :dirty
0
       base.alias_method_chain :save,            :dirty
0
       base.alias_method_chain :save!,           :dirty
0
@@ -44,6 +46,8 @@ module ActiveRecord
0
 
0
       base.superclass_delegating_accessor :partial_updates
0
       base.partial_updates = true
0
+
0
+      base.send(:extend, ClassMethods)
0
     end
0
 
0
     # Do any attributes have unsaved changes?
0
@@ -161,5 +165,19 @@ module ActiveRecord
0
         old != value
0
       end
0
 
0
+    module ClassMethods
0
+      def self.extended(base)
0
+        base.metaclass.alias_method_chain(:alias_attribute, :dirty)
0
+      end
0
+
0
+      def alias_attribute_with_dirty(new_name, old_name)
0
+        alias_attribute_without_dirty(new_name, old_name)
0
+        DIRTY_SUFFIXES.each do |suffix|
0
+          module_eval <<-STR, __FILE__, __LINE__+1
0
+            def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end
0
+          STR
0
+        end
0
+      end
0
+    end
0
   end
0
 end
...
45
46
47
 
 
 
 
 
 
 
 
 
 
 
 
 
48
49
50
...
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
0
@@ -45,6 +45,19 @@ class DirtyTest < ActiveRecord::TestCase
0
     assert_nil pirate.catchphrase_change
0
   end
0
 
0
+  def test_aliased_attribute_changes
0
+    # the actual attribute here is name, title is an
0
+    # alias setup via alias_attribute
0
+    parrot = Parrot.new
0
+    assert !parrot.title_changed?
0
+    assert_nil parrot.title_change
0
+
0
+    parrot.name = 'Sam'
0
+    assert parrot.title_changed?
0
+    assert_nil parrot.title_was
0
+    assert_equal parrot.name_change, parrot.title_change
0
+  end
0
+
0
   def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank
0
     pirate = Pirate.new
0
 
...
3
4
5
 
6
7
8
...
3
4
5
6
7
8
9
0
@@ -3,6 +3,7 @@ class Parrot < ActiveRecord::Base
0
   has_and_belongs_to_many :pirates
0
   has_and_belongs_to_many :treasures
0
   has_many :loots, :as => :looter
0
+  alias_attribute :title, :name
0
 end
0
 
0
 class LiveParrot < Parrot

Comments