aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorMarcin Raczkowski <marcin.raczkowski@gmail.com>2010-09-06 03:30:06 +0200
committerEmilio Tagua <miloops@gmail.com>2010-11-19 19:04:40 -0300
commiteebf33a2347bd4717b6ce966c2b7def4d573ec51 (patch)
treedf3e9e61f1331b012d1a84eba434647e7630e28f /activerecord
parentccb335da1f293dc745be0171ce3d95e50223d934 (diff)
downloadrails-eebf33a2347bd4717b6ce966c2b7def4d573ec51.tar.gz
rails-eebf33a2347bd4717b6ce966c2b7def4d573ec51.tar.bz2
rails-eebf33a2347bd4717b6ce966c2b7def4d573ec51.zip
IdentityMap - Fixes problem with dirty attributes
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/base.rb3
-rw-r--r--activerecord/test/cases/identity_map_test.rb32
-rw-r--r--activerecord/test/cases/nested_attributes_test.rb4
3 files changed, 34 insertions, 5 deletions
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index d7e58ba978..c12633347e 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -899,8 +899,9 @@ module ActiveRecord #:nodoc:
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)
diff --git a/activerecord/test/cases/identity_map_test.rb b/activerecord/test/cases/identity_map_test.rb
index bc0ceae605..d157443b7b 100644
--- a/activerecord/test/cases/identity_map_test.rb
+++ b/activerecord/test/cases/identity_map_test.rb
@@ -16,6 +16,9 @@ require 'models/sponsor'
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,
@@ -70,6 +73,35 @@ class IdentityMapTest < ActiveRecord::TestCase
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
diff --git a/activerecord/test/cases/nested_attributes_test.rb b/activerecord/test/cases/nested_attributes_test.rb
index e4697ae4a4..20a24c38fa 100644
--- a/activerecord/test/cases/nested_attributes_test.rb
+++ b/activerecord/test/cases/nested_attributes_test.rb
@@ -554,11 +554,7 @@ module NestedAttributesOnACollectionAssociationTests
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