From 301dd3d5143077f95bebd434ca2ad1c80c1b5866 Mon Sep 17 00:00:00 2001 From: Emilio Tagua Date: Thu, 14 Oct 2010 12:58:47 -0300 Subject: Use hash[:Post][1] style identity maps for each table. --- .../lib/active_record/associations/association_proxy.rb | 6 +++--- activerecord/lib/active_record/base.rb | 9 ++++++++- activerecord/lib/active_record/identity_map.rb | 14 +++++++++----- activerecord/test/cases/identity_map_test.rb | 7 +++++++ 4 files changed, 27 insertions(+), 9 deletions(-) (limited to 'activerecord') 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'), -- cgit v1.2.3