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

Raise error when passing passing a class to :source_type

Raise `ArgumentError` when `:source_type` is given as class
in `has_many :through` relation.

Closes #41092
This commit is contained in:
Jacopo 2021-01-20 12:40:35 +01:00
parent ddaceddeab
commit 6c6b2d08e2
2 changed files with 16 additions and 3 deletions

View file

@ -306,6 +306,12 @@ module ActiveRecord
def primary_key(klass) def primary_key(klass)
klass.primary_key || raise(UnknownPrimaryKey.new(klass)) klass.primary_key || raise(UnknownPrimaryKey.new(klass))
end end
def ensure_option_not_given_as_class!(option_name)
if options[option_name] && options[option_name].class == Class
raise ArgumentError, "A class was passed to `:#{option_name}` but we are expecting a string."
end
end
end end
# Base class for AggregateReflection and AssociationReflection. Objects of # Base class for AggregateReflection and AssociationReflection. Objects of
@ -426,9 +432,7 @@ module ActiveRecord
@type = -(options[:foreign_type]&.to_s || "#{options[:as]}_type") if options[:as] @type = -(options[:foreign_type]&.to_s || "#{options[:as]}_type") if options[:as]
@foreign_type = -(options[:foreign_type]&.to_s || "#{name}_type") if options[:polymorphic] @foreign_type = -(options[:foreign_type]&.to_s || "#{name}_type") if options[:polymorphic]
if options[:class_name] && options[:class_name].class == Class ensure_option_not_given_as_class!(:class_name)
raise ArgumentError, "A class was passed to `:class_name` but we are expecting a string."
end
end end
def association_scope_cache(klass, owner, &block) def association_scope_cache(klass, owner, &block)
@ -748,6 +752,8 @@ module ActiveRecord
@delegate_reflection = delegate_reflection @delegate_reflection = delegate_reflection
@klass = delegate_reflection.options[:anonymous_class] @klass = delegate_reflection.options[:anonymous_class]
@source_reflection_name = delegate_reflection.options[:source] @source_reflection_name = delegate_reflection.options[:source]
ensure_option_not_given_as_class!(:source_type)
end end
def through_reflection? def through_reflection?

View file

@ -432,6 +432,13 @@ class ReflectionTest < ActiveRecord::TestCase
assert_equal "A class was passed to `:class_name` but we are expecting a string.", error.message assert_equal "A class was passed to `:class_name` but we are expecting a string.", error.message
end end
def test_class_for_source_type
error = assert_raises(ArgumentError) do
ActiveRecord::Reflection.create(:has_many, :tagged_posts, nil, { through: :taggings, source: :taggable, source_type: Post }, Tag)
end
assert_equal "A class was passed to `:source_type` but we are expecting a string.", error.message
end
def test_join_table def test_join_table
category = Struct.new(:table_name, :pluralize_table_names).new("categories", true) category = Struct.new(:table_name, :pluralize_table_names).new("categories", true)
product = Struct.new(:table_name, :pluralize_table_names).new("products", true) product = Struct.new(:table_name, :pluralize_table_names).new("products", true)