提交 ddc52a1d 编写于 作者: R Ryuta Kamizono

Extract all `base_class.name` as `polymorphic_name`

This is an alternative of #29722, and follow up of #32048.

This does not change the current behavior, but makes it easier to modify
all polymorphic names consistently.
上级 0168db7d
......@@ -201,8 +201,8 @@ def creation_attributes
if (reflection.has_one? || reflection.collection?) && !options[:through]
attributes[reflection.foreign_key] = owner[reflection.active_record_primary_key]
if reflection.options[:as]
attributes[reflection.type] = owner.class.base_class.name
if reflection.type
attributes[reflection.type] = owner.class.polymorphic_name
end
end
......
......@@ -35,12 +35,12 @@ def self.get_bind_values(owner, chain)
binds << last_reflection.join_id_for(owner)
if last_reflection.type
binds << owner.class.base_class.name
binds << owner.class.polymorphic_name
end
chain.each_cons(2).each do |reflection, next_reflection|
if reflection.type
binds << next_reflection.klass.base_class.name
binds << next_reflection.klass.polymorphic_name
end
end
binds
......@@ -67,7 +67,7 @@ def last_chain_scope(scope, reflection, owner)
scope = apply_scope(scope, table, key, value)
if reflection.type
polymorphic_type = transform_value(owner.class.base_class.name)
polymorphic_type = transform_value(owner.class.polymorphic_name)
scope = apply_scope(scope, table, reflection.type, polymorphic_type)
end
......@@ -88,7 +88,7 @@ def next_chain_scope(scope, reflection, next_reflection)
constraint = table[key].eq(foreign_table[foreign_key])
if reflection.type
value = transform_value(next_reflection.klass.base_class.name)
value = transform_value(next_reflection.klass.polymorphic_name)
scope = apply_scope(scope, table, reflection.type, value)
end
......
......@@ -13,7 +13,7 @@ def klass
def replace_keys(record)
super
owner[reflection.foreign_type] = record ? record.class.base_class.name : nil
owner[reflection.foreign_type] = record ? record.class.polymorphic_name : nil
end
def different_target?(record)
......
......@@ -118,7 +118,7 @@ def build_scope
scope = klass.scope_for_association
if reflection.type
scope.where!(reflection.type => model.base_class.name)
scope.where!(reflection.type => model.polymorphic_name)
end
scope.merge!(reflection_scope) if reflection.scope
......
......@@ -156,6 +156,10 @@ def sti_name
store_full_sti_class ? name : name.demodulize
end
def polymorphic_name
base_class.name
end
def inherited(subclass)
subclass.instance_variable_set(:@_type_candidates_cache, Concurrent::Map.new)
super
......
......@@ -193,7 +193,7 @@ def join_scope(table, foreign_klass)
klass_scope = klass_join_scope(table, predicate_builder)
if type
klass_scope.where!(type => foreign_klass.base_class.name)
klass_scope.where!(type => foreign_klass.polymorphic_name)
end
scope_chain_items.inject(klass_scope, &:merge!)
......
......@@ -25,19 +25,21 @@ def queries
private
def type_to_ids_mapping
default_hash = Hash.new { |hsh, key| hsh[key] = [] }
values.each_with_object(default_hash) { |value, hash| hash[base_class(value).name] << convert_to_id(value) }
values.each_with_object(default_hash) do |value, hash|
hash[klass(value).polymorphic_name] << convert_to_id(value)
end
end
def primary_key(value)
associated_table.association_join_primary_key(base_class(value))
associated_table.association_join_primary_key(klass(value))
end
def base_class(value)
def klass(value)
case value
when Base
value.class.base_class
value.class
when Relation
value.klass.base_class
value.klass
end
end
......
......@@ -8,6 +8,10 @@ module Namespaced
class Post < ActiveRecord::Base
self.table_name = "posts"
has_one :tagging, as: :taggable, class_name: "Tagging"
def self.polymorphic_name
sti_name
end
end
end
......@@ -25,34 +29,44 @@ def teardown
end
def test_class_names
ActiveRecord::Base.store_full_sti_class = false
ActiveRecord::Base.store_full_sti_class = !store_full_sti_class
post = Namespaced::Post.find_by_title("Great stuff")
assert_equal @tagging, post.tagging
assert_nil post.tagging
ActiveRecord::Base.store_full_sti_class = true
ActiveRecord::Base.store_full_sti_class = store_full_sti_class
post = Namespaced::Post.find_by_title("Great stuff")
assert_equal @tagging, post.tagging
end
def test_class_names_with_includes
ActiveRecord::Base.store_full_sti_class = false
ActiveRecord::Base.store_full_sti_class = !store_full_sti_class
post = Namespaced::Post.includes(:tagging).find_by_title("Great stuff")
assert_equal @tagging, post.tagging
assert_nil post.tagging
ActiveRecord::Base.store_full_sti_class = true
ActiveRecord::Base.store_full_sti_class = store_full_sti_class
post = Namespaced::Post.includes(:tagging).find_by_title("Great stuff")
assert_equal @tagging, post.tagging
end
def test_class_names_with_eager_load
ActiveRecord::Base.store_full_sti_class = false
ActiveRecord::Base.store_full_sti_class = !store_full_sti_class
post = Namespaced::Post.eager_load(:tagging).find_by_title("Great stuff")
assert_equal @tagging, post.tagging
assert_nil post.tagging
ActiveRecord::Base.store_full_sti_class = true
ActiveRecord::Base.store_full_sti_class = store_full_sti_class
post = Namespaced::Post.eager_load(:tagging).find_by_title("Great stuff")
assert_equal @tagging, post.tagging
end
def test_class_names_with_find_by
post = Namespaced::Post.find_by_title("Great stuff")
ActiveRecord::Base.store_full_sti_class = !store_full_sti_class
assert_nil Tagging.find_by(taggable: post)
ActiveRecord::Base.store_full_sti_class = store_full_sti_class
assert_equal @tagging, Tagging.find_by(taggable: post)
end
end
class PolymorphicFullStiClassNamesTest < ActiveRecord::TestCase
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册