Skip to content

Commit

Permalink
IdentityMap - Fixes problem with dirty attributes
Browse files Browse the repository at this point in the history
  • Loading branch information
swistak authored and miloops committed Nov 19, 2010
1 parent ccb335d commit eebf33a
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 5 deletions.
3 changes: 2 additions & 1 deletion activerecord/lib/active_record/base.rb
Original file line number Diff line number Diff line change
Expand Up @@ -899,8 +899,9 @@ def instantiate(record)
record_id = sti_class.primary_key && record[sti_class.primary_key]
if ActiveRecord::IdentityMap.enabled? && record_id
if object = identity_map.get(sti_class.name, record_id)
object.instance_variable_get("@attributes").update(record)
object.instance_variable_get("@attributes_cache").replace({})
object.instance_variable_get("@changed_attributes").update(record.slice(*object.changed))
object.instance_variable_get("@attributes").update(record.except(*object.changed))
else
object = instantiate_without_im(sti_class.allocate, record)
identity_map.add(object)
Expand Down
32 changes: 32 additions & 0 deletions activerecord/test/cases/identity_map_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
require 'models/member'
require 'models/essay'
require 'models/subscriber'
require "models/pirate"
require "models/bird"
require "models/parrot"

class IdentityMapTest < ActiveRecord::TestCase
fixtures :accounts, :companies, :developers, :projects, :topics,
Expand Down Expand Up @@ -70,6 +73,35 @@ def test_creation
assert_same(t1, t2)
end

def test_loading_new_instance_should_not_update_dirty_attributes
swistak = Subscriber.find(:first, :conditions => {:nick => 'swistak'})
swistak.name = "Swistak Sreberkowiec"
assert_equal(["name"], swistak.changed)

s = Subscriber.find('swistak')

assert swistak.name_changed?
assert_equal("Swistak Sreberkowiec", swistak.name)
end

def test_loading_new_instance_should_remove_dirt
#assert_equal({'name' => ["Marcin Raczkowski", "Swistak Sreberkowiec"]}, swistak.changes)
#assert_equal("Swistak Sreberkowiec", swistak.name)
end

def test_has_many_associations
pirate = Pirate.create!(:catchphrase => "Don' botharrr talkin' like one, savvy?")
pirate.birds.create!(:name => 'Posideons Killer')
pirate.birds.create!(:name => 'Killer bandita Dionne')

posideons, killer = pirate.birds

pirate.reload

pirate.birds_attributes = [{ :id => posideons.id, :name => 'Grace OMalley' }]
assert_equal 'Grace OMalley', pirate.birds.send(:load_target).find { |r| r.id == posideons.id }.name
end

# Currently AR is not allowing changing primary key (see Persistence#update)
# So we ignore it. If this changes, this test needs to be uncommented.
# def test_updating_of_pkey
Expand Down
4 changes: 0 additions & 4 deletions activerecord/test/cases/nested_attributes_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -554,11 +554,7 @@ def test_should_not_load_association_when_updating_existing_records

def test_should_not_overwrite_unsaved_updates_when_loading_association
@pirate.reload
# p(@pirate.send(@association_name))
@pirate.send(association_setter, [{ :id => @child_1.id, :name => 'Grace OMalley' }])
# p(@pirate.send(@association_name))
# p([@pirate.send(@association_name).detect { |r| r.id == @child_1.id }, @child_1.id])
# puts
assert_equal 'Grace OMalley', @pirate.send(@association_name).send(:load_target).find { |r| r.id == @child_1.id }.name
end

Expand Down

0 comments on commit eebf33a

Please sign in to comment.