Skip to content

Commit

Permalink
Allow for the dirty tracking to work with the aliased name of aliased…
Browse files Browse the repository at this point in the history
… attributes.

Signed-off-by: Michael Koziarski <michael@koziarski.com>
[#812 state:committed]
  • Loading branch information
rich authored and NZKoz committed Sep 13, 2008
1 parent fcf31cb commit 113de01
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 1 deletion.
20 changes: 19 additions & 1 deletion activerecord/lib/active_record/dirty.rb
Expand Up @@ -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
Expand All @@ -44,6 +46,8 @@ def self.included(base)

base.superclass_delegating_accessor :partial_updates
base.partial_updates = true

base.send(:extend, ClassMethods)
end

# Do any attributes have unsaved changes?
Expand Down Expand Up @@ -161,5 +165,19 @@ def field_changed?(attr, old, value)
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
13 changes: 13 additions & 0 deletions activerecord/test/cases/dirty_test.rb
Expand Up @@ -45,6 +45,19 @@ def test_attribute_changes
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

Expand Down
1 change: 1 addition & 0 deletions activerecord/test/models/parrot.rb
Expand Up @@ -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
Expand Down

0 comments on commit 113de01

Please sign in to comment.