1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Have a proper AssociationReflection#foreign_type method rather than using options[:foreign_type]

This commit is contained in:
Jon Leighton 2011-01-01 18:52:48 +00:00 committed by Aaron Patterson
parent d18a27031f
commit c47f802d0e
8 changed files with 24 additions and 28 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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?