aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activerecord/lib/active_record/associations/association_proxy.rb6
-rw-r--r--activerecord/lib/active_record/base.rb9
-rw-r--r--activerecord/lib/active_record/identity_map.rb14
-rw-r--r--activerecord/test/cases/identity_map_test.rb7
4 files changed, 27 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/associations/association_proxy.rb b/activerecord/lib/active_record/associations/association_proxy.rb
index 2024cee968..52cb164550 100644
--- a/activerecord/lib/active_record/associations/association_proxy.rb
+++ b/activerecord/lib/active_record/associations/association_proxy.rb
@@ -253,9 +253,9 @@ module ActiveRecord
def load_target
return nil unless defined?(@loaded)
- if !loaded? and (!@owner.persisted? || foreign_key_present)
- if IdentityMap.enabled?
- @target = IdentityMap.get(@reflection.class_name, @owner[@reflection.association_foreign_key])
+ if !loaded? and (@owner.persisted? || foreign_key_present)
+ if IdentityMap.enabled? && defined?(@reflection.klass)
+ @target = IdentityMap.get(@reflection.klass, @owner[@reflection.association_foreign_key])
end
@target ||= find_target
end
diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb
index 8a8166fb1c..2ac4b6a00a 100644
--- a/activerecord/lib/active_record/base.rb
+++ b/activerecord/lib/active_record/base.rb
@@ -792,6 +792,10 @@ module ActiveRecord #:nodoc:
object.is_a?(self)
end
+ def symbolized_base_class
+ @symbolized_base_class ||= base_class.to_s.to_sym
+ end
+
# Returns the base AR subclass that this class descends from. If A
# extends AR::Base, A.base_class will return A. If B descends from A
# through some arbitrarily deep hierarchy, B.base_class will return A.
@@ -887,7 +891,10 @@ module ActiveRecord #:nodoc:
record_id = sti_class.primary_key && record[sti_class.primary_key]
if ActiveRecord::IdentityMap.enabled? && record_id
- if instance = identity_map.get(sti_class.name, record_id)
+ if (column = sti_class.columns_hash[sti_class.primary_key]) && column.number?
+ record_id = record_id.to_i
+ end
+ if instance = identity_map.get(sti_class, record_id)
instance.reinit_with('attributes' => record)
else
instance = sti_class.allocate.init_with('attributes' => record)
diff --git a/activerecord/lib/active_record/identity_map.rb b/activerecord/lib/active_record/identity_map.rb
index d605bde5b2..d7ba1d953c 100644
--- a/activerecord/lib/active_record/identity_map.rb
+++ b/activerecord/lib/active_record/identity_map.rb
@@ -23,7 +23,7 @@ module ActiveRecord
attr_accessor :enabled
def current
- repositories[current_repository_name] ||= Weakling::WeakHash.new
+ repositories[current_repository_name] ||= Hash.new { |h,k| h[k] = Weakling::WeakHash.new }
end
def with_repository(name = :default)
@@ -43,16 +43,20 @@ module ActiveRecord
self.enabled = old
end
- def get(class_name, primary_key)
- current[[class_name, primary_key.to_s]]
+ def get(klass, primary_key)
+ if obj = current[klass.symbolized_base_class][primary_key]
+ return obj if obj.id == primary_key && klass == obj.class
+ end
+
+ nil
end
def add(record)
- current[[record.class.name, record.id.to_s]] = record
+ current[record.class.symbolized_base_class][record.id] = record
end
def remove(record)
- current.delete([record.class.name, record.id.to_s])
+ current[record.class.symbolized_base_class].delete(record.id)
end
def clear
diff --git a/activerecord/test/cases/identity_map_test.rb b/activerecord/test/cases/identity_map_test.rb
index f984c42ffb..1588633e1d 100644
--- a/activerecord/test/cases/identity_map_test.rb
+++ b/activerecord/test/cases/identity_map_test.rb
@@ -53,6 +53,13 @@ class IdentityMapTest < ActiveRecord::TestCase
)
end
+ def test_find_by_string_and_numeric_id
+ assert_same(
+ Client.find_by_id("3"),
+ Client.find_by_id(3)
+ )
+ end
+
def test_find_by_pkey
assert_same(
Subscriber.find_by_nick('swistak'),