From 113de01eaf48f64d2adf9f34d699e51619af616f Mon Sep 17 00:00:00 2001 From: Rich Cavanaugh Date: Fri, 15 Aug 2008 21:49:22 -0400 Subject: Allow for the dirty tracking to work with the aliased name of aliased attributes. Signed-off-by: Michael Koziarski [#812 state:committed] --- activerecord/lib/active_record/dirty.rb | 20 +++++++++++++++++++- activerecord/test/cases/dirty_test.rb | 13 +++++++++++++ activerecord/test/models/parrot.rb | 1 + 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'activerecord') diff --git a/activerecord/lib/active_record/dirty.rb b/activerecord/lib/active_record/dirty.rb index 7e246e62ca..ae573799ae 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,8 @@ module ActiveRecord base.superclass_delegating_accessor :partial_updates base.partial_updates = true + + base.send(:extend, ClassMethods) end # Do any attributes have unsaved changes? @@ -161,5 +165,19 @@ module ActiveRecord old != value end + module ClassMethods + def self.extended(base) + base.metaclass.alias_method_chain(:alias_attribute, :dirty) + end + + 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 4fe1d79f4d..39d38c4e1e 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 65191c1aa5..b9431fd1c0 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 -- cgit v1.2.3