From cec1e4e40fdacc7a1ccd87381ce8c991b299c596 Mon Sep 17 00:00:00 2001 From: Rich Cavanaugh Date: Fri, 15 Aug 2008 21:49:22 -0400 Subject: [PATCH] Overrode alias_attribute in the Dirty module to allow for the dirty tracking to work on aliased attributes. --- activerecord/lib/active_record/dirty.rb | 19 +++++++++++++++++-- activerecord/test/cases/dirty_test.rb | 13 +++++++++++++ activerecord/test/models/parrot.rb | 1 + 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index 63bf8c8..9cb32cd 100644 --- a/activerecord/lib/active_record/dirty.rb +++ b/activerecord/lib/active_record/dirty.rb @@ -34,8 +34,10 @@ module ActiveRecord # person.name << 'by' # person.name_change # => ['uncle bob', 'uncle bobby'] module Dirty + DIRTY_SUFFIXES = ['_changed?', '_change', '_will_change!', '_was'] + def self.included(base) - base.attribute_method_suffix '_changed?', '_change', '_will_change!', '_was' + base.attribute_method_suffix *DIRTY_SUFFIXES base.alias_method_chain :write_attribute, :dirty base.alias_method_chain :save, :dirty base.alias_method_chain :save!, :dirty @@ -44,6 +46,9 @@ module ActiveRecord base.superclass_delegating_accessor :partial_updates base.partial_updates = true + + base.send(:extend, ClassMethods) + base.metaclass.alias_method_chain(:alias_attribute, :dirty) end # Do any attributes have unsaved changes? @@ -157,6 +162,16 @@ module ActiveRecord old != value end - + + module ClassMethods + def alias_attribute_with_dirty(new_name, old_name) + alias_attribute_without_dirty(new_name, old_name) + DIRTY_SUFFIXES.each do |suffix| + module_eval <<-STR, __FILE__, __LINE__+1 + def #{new_name}#{suffix}; self.#{old_name}#{suffix}; end + STR + end + end + end end end diff --git a/activerecord/test/cases/dirty_test.rb b/activerecord/test/cases/dirty_test.rb index feb47a1..821195f 100644 --- a/activerecord/test/cases/dirty_test.rb +++ b/activerecord/test/cases/dirty_test.rb @@ -45,6 +45,19 @@ class DirtyTest < ActiveRecord::TestCase assert_nil pirate.catchphrase_change end + def test_aliased_attribute_changes + # the actual attribute here is name, title is an + # alias setup via alias_attribute + parrot = Parrot.new + assert !parrot.title_changed? + assert_nil parrot.title_change + + parrot.name = 'Sam' + assert parrot.title_changed? + assert_nil parrot.title_was + assert_equal parrot.name_change, parrot.title_change + end + def test_nullable_integer_not_marked_as_changed_if_new_value_is_blank pirate = Pirate.new diff --git a/activerecord/test/models/parrot.rb b/activerecord/test/models/parrot.rb index 65191c1..b9431fd 100644 --- a/activerecord/test/models/parrot.rb +++ b/activerecord/test/models/parrot.rb @@ -3,6 +3,7 @@ class Parrot < ActiveRecord::Base has_and_belongs_to_many :pirates has_and_belongs_to_many :treasures has_many :loots, :as => :looter + alias_attribute :title, :name end class LiveParrot < Parrot -- 1.5.6.2