Merge pull request #37500 from rafaelfranca/rm-sti-config

Add methods to the public API of ActiveRecord::Inheritance
This commit is contained in:
Rafael França 2019-10-17 17:51:51 -04:00 committed by GitHub
commit b305f0e206
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 14 deletions

View File

@ -6,7 +6,7 @@ module ActiveRecord
class BelongsToPolymorphicAssociation < BelongsToAssociation #:nodoc:
def klass
type = owner[reflection.foreign_type]
type.presence && type.constantize
type.presence && owner.class.polymorphic_class_for(type)
end
def target_changed?

View File

@ -162,14 +162,40 @@ module ActiveRecord
defined?(@abstract_class) && @abstract_class == true
end
# Returns the value to be stored in the inheritance column for STI.
def sti_name
store_full_sti_class ? name : name.demodulize
end
# Returns the class for the provided +type_name+.
#
# It is used to find the class correspondent to the value stored in the inheritance column.
def sti_class_for(type_name)
if store_full_sti_class
ActiveSupport::Dependencies.constantize(type_name)
else
compute_type(type_name)
end
rescue NameError
raise SubclassNotFound,
"The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
"This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
"Please rename this column if you didn't intend it to be used for storing the inheritance class " \
"or overwrite #{name}.inheritance_column to use another column for that information."
end
# Returns the value to be stored in the polymorphic type column for Polymorphic Associations.
def polymorphic_name
base_class.name
end
# Returns the class for the provided +name+.
#
# It is used to find the class correspondent to the value stored in the polymorphic type column.
def polymorphic_class_for(name)
name.constantize
end
def inherited(subclass)
subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
super
@ -224,22 +250,12 @@ module ActiveRecord
def find_sti_class(type_name)
type_name = base_class.type_for_attribute(inheritance_column).cast(type_name)
subclass = begin
if store_full_sti_class
ActiveSupport::Dependencies.constantize(type_name)
else
compute_type(type_name)
end
rescue NameError
raise SubclassNotFound,
"The single-table inheritance mechanism failed to locate the subclass: '#{type_name}'. " \
"This error is raised because the column '#{inheritance_column}' is reserved for storing the class in case of inheritance. " \
"Please rename this column if you didn't intend it to be used for storing the inheritance class " \
"or overwrite #{name}.inheritance_column to use another column for that information."
end
subclass = sti_class_for(type_name)
unless subclass == self || descendants.include?(subclass)
raise SubclassNotFound, "Invalid single-table inheritance type: #{subclass.name} is not a subclass of #{name}"
end
subclass
end