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:
parent
d18a27031f
commit
c47f802d0e
8 changed files with 24 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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?
|
||||
|
|
Loading…
Reference in a new issue