From c47f802d0e7b0156512f197887d6e9bda6d0f269 Mon Sep 17 00:00:00 2001 From: Jon Leighton Date: Sat, 1 Jan 2011 18:52:48 +0000 Subject: Have a proper AssociationReflection#foreign_type method rather than using options[:foreign_type] --- activerecord/lib/active_record/association_preload.rb | 11 ++++------- activerecord/lib/active_record/associations.rb | 8 +------- .../associations/belongs_to_polymorphic_association.rb | 6 +++--- .../class_methods/join_dependency/join_association.rb | 2 +- .../lib/active_record/associations/through_association.rb | 4 ++-- activerecord/lib/active_record/fixtures.rb | 11 +++-------- activerecord/lib/active_record/reflection.rb | 4 ++++ activerecord/test/cases/reflection_test.rb | 6 ++++++ 8 files changed, 24 insertions(+), 28 deletions(-) diff --git a/activerecord/lib/active_record/association_preload.rb b/activerecord/lib/active_record/association_preload.rb index 638897a86b..e3aee701a8 100644 --- a/activerecord/lib/active_record/association_preload.rb +++ b/activerecord/lib/active_record/association_preload.rb @@ -287,7 +287,7 @@ module ActiveRecord def preload_through_records(records, reflection, through_association) if reflection.options[:source_type] - interface = reflection.source_reflection.options[:foreign_type] + interface = reflection.source_reflection.foreign_type preload_options = {:conditions => ["#{connection.quote_column_name interface} = ?", reflection.options[:source_type]]} records.compact! @@ -319,18 +319,15 @@ module ActiveRecord def preload_belongs_to_association(records, reflection, preload_options={}) return if records.first.send("loaded_#{reflection.name}?") options = reflection.options - foreign_key = reflection.foreign_key klasses_and_ids = {} if options[:polymorphic] - polymorph_type = options[:foreign_type] - # Construct a mapping from klass to a list of ids to load and a mapping of those ids back # to their parent_records records.each do |record| - if klass = record.send(polymorph_type) - klass_id = record.send(foreign_key) + if klass = record.send(reflection.foreign_type) + klass_id = record.send(reflection.foreign_key) if klass_id id_map = klasses_and_ids[klass.constantize] ||= {} (id_map[klass_id.to_s] ||= []) << record @@ -339,7 +336,7 @@ module ActiveRecord end else id_map = records.group_by do |record| - key = record.send(foreign_key) + key = record.send(reflection.foreign_key) key && key.to_s end id_map.delete nil diff --git a/activerecord/lib/active_record/associations.rb b/activerecord/lib/active_record/associations.rb index 0c71e76899..b3d5a29b16 100644 --- a/activerecord/lib/active_record/associations.rb +++ b/activerecord/lib/active_record/associations.rb @@ -1761,13 +1761,7 @@ module ActiveRecord def create_belongs_to_reflection(association_id, options) options.assert_valid_keys(valid_keys_for_belongs_to_association) - reflection = create_reflection(:belongs_to, association_id, options, self) - - if options[:polymorphic] - reflection.options[:foreign_type] ||= reflection.class_name.underscore + "_type" - end - - reflection + create_reflection(:belongs_to, association_id, options, self) end mattr_accessor :valid_keys_for_has_and_belongs_to_many_association diff --git a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb index 46adc048b8..4608ffad67 100644 --- a/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb +++ b/activerecord/lib/active_record/associations/belongs_to_polymorphic_association.rb @@ -7,7 +7,7 @@ module ActiveRecord target_id = @target.send(@reflection.association_primary_key).to_s foreign_key = @owner.send(@reflection.foreign_key).to_s target_type = @target.class.base_class.name - foreign_type = @owner.send(@reflection.options[:foreign_type]).to_s + foreign_type = @owner.send(@reflection.foreign_type).to_s target_id != foreign_key || target_type != foreign_type else @@ -19,7 +19,7 @@ module ActiveRecord def replace_keys(record) super - @owner[@reflection.options[:foreign_type]] = record && record.class.base_class.name + @owner[@reflection.foreign_type] = record && record.class.base_class.name end def different_target?(record) @@ -31,7 +31,7 @@ module ActiveRecord end def target_klass - type = @owner[@reflection.options[:foreign_type]] + type = @owner[@reflection.foreign_type] type && type.constantize end diff --git a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb index 1e5149d80f..3fea24ebf8 100644 --- a/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb +++ b/activerecord/lib/active_record/associations/class_methods/join_dependency/join_association.rb @@ -228,7 +228,7 @@ module ActiveRecord second_key = source_reflection.association_foreign_key jt_conditions << - join_table[reflection.source_reflection.options[:foreign_type]]. + join_table[reflection.source_reflection.foreign_type]. eq(reflection.options[:source_type]) else second_key = source_reflection.foreign_key diff --git a/activerecord/lib/active_record/associations/through_association.rb b/activerecord/lib/active_record/associations/through_association.rb index c78f5d969f..6536fb44b2 100644 --- a/activerecord/lib/active_record/associations/through_association.rb +++ b/activerecord/lib/active_record/associations/through_association.rb @@ -71,7 +71,7 @@ module ActiveRecord @reflection.klass.primary_key source_primary_key = @reflection.source_reflection.foreign_key if @reflection.options[:source_type] - column = @reflection.source_reflection.options[:foreign_type] + column = @reflection.source_reflection.foreign_type conditions << right[column].eq(@reflection.options[:source_type]) end @@ -105,7 +105,7 @@ module ActiveRecord } if @reflection.options[:source_type] - join_attributes.merge!(@reflection.source_reflection.options[:foreign_type] => associate.class.base_class.name) + join_attributes.merge!(@reflection.source_reflection.foreign_type => associate.class.base_class.name) end if @reflection.through_reflection.options[:conditions].is_a?(Hash) diff --git a/activerecord/lib/active_record/fixtures.rb b/activerecord/lib/active_record/fixtures.rb index 3ddd6687b9..b6f0511b9a 100644 --- a/activerecord/lib/active_record/fixtures.rb +++ b/activerecord/lib/active_record/fixtures.rb @@ -615,14 +615,9 @@ class Fixtures < (RUBY_VERSION < '1.9' ? YAML::Omap : Hash) fk_name = (association.options[:foreign_key] || "#{association.name}_id").to_s if association.name.to_s != fk_name && value = row.delete(association.name.to_s) - if association.options[:polymorphic] - if value.sub!(/\s*\(([^\)]*)\)\s*$/, "") - target_type = $1 - target_type_name = (association.options[:foreign_type] || "#{association.name}_type").to_s - - # support polymorphic belongs_to as "label (Type)" - row[target_type_name] = target_type - end + if association.options[:polymorphic] && value.sub!(/\s*\(([^\)]*)\)\s*$/, "") + # support polymorphic belongs_to as "label (Type)" + row[association.foreign_type] = $1 end row[fk_name] = Fixtures.identify(value) diff --git a/activerecord/lib/active_record/reflection.rb b/activerecord/lib/active_record/reflection.rb index 81a95d4971..bc5824104e 100644 --- a/activerecord/lib/active_record/reflection.rb +++ b/activerecord/lib/active_record/reflection.rb @@ -200,6 +200,10 @@ module ActiveRecord @foreign_key ||= options[:foreign_key] || derive_foreign_key end + def foreign_type + @foreign_type ||= options[:foreign_type] || "#{name}_type" + end + def primary_key_column @primary_key_column ||= klass.columns.find { |c| c.name == klass.primary_key } end diff --git a/activerecord/test/cases/reflection_test.rb b/activerecord/test/cases/reflection_test.rb index e3db34520e..081e3cc861 100644 --- a/activerecord/test/cases/reflection_test.rb +++ b/activerecord/test/cases/reflection_test.rb @@ -10,6 +10,7 @@ require 'models/price_estimate' require 'models/tagging' require 'models/author' require 'models/post' +require 'models/sponsor' class ReflectionTest < ActiveRecord::TestCase include ActiveRecord::Reflection @@ -205,6 +206,11 @@ class ReflectionTest < ActiveRecord::TestCase assert_equal "name", Author.reflect_on_association(:essay).active_record_primary_key.to_s end + def test_foreign_type + assert_equal "sponsorable_type", Sponsor.reflect_on_association(:sponsorable).foreign_type.to_s + assert_equal "sponsorable_type", Sponsor.reflect_on_association(:thing).foreign_type.to_s + end + def test_collection_association assert Pirate.reflect_on_association(:birds).collection? assert Pirate.reflect_on_association(:parrots).collection? -- cgit v1.2.3