mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Fix has_one through reflection casting check
Fixes a bug where has_one through relations with non-integer primary keys were incorrectly raising an implementation error even though a reflectable association was present.
This commit is contained in:
parent
352560308b
commit
d739c835bc
2 changed files with 63 additions and 9 deletions
|
@ -766,7 +766,8 @@ module ActiveRecord
|
||||||
def klass
|
def klass
|
||||||
@klass ||= delegate_reflection.compute_class(class_name).tap do |klass|
|
@klass ||= delegate_reflection.compute_class(class_name).tap do |klass|
|
||||||
if !parent_reflection.is_a?(HasAndBelongsToManyReflection) &&
|
if !parent_reflection.is_a?(HasAndBelongsToManyReflection) &&
|
||||||
!klass.reflections.include?(options[:through].to_s) &&
|
!(klass.reflections.key?(options[:through].to_s) ||
|
||||||
|
klass.reflections.key?(options[:through].to_s.pluralize)) &&
|
||||||
active_record.type_for_attribute(active_record.primary_key).type != :integer
|
active_record.type_for_attribute(active_record.primary_key).type != :integer
|
||||||
raise NotImplementedError, <<~MSG.squish
|
raise NotImplementedError, <<~MSG.squish
|
||||||
In order to correctly type cast #{active_record}.#{active_record.primary_key},
|
In order to correctly type cast #{active_record}.#{active_record.primary_key},
|
||||||
|
|
|
@ -256,14 +256,6 @@ class ReflectionTest < ActiveRecord::TestCase
|
||||||
assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
|
assert_kind_of ThroughReflection, Subscriber.reflect_on_association(:books)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_uncastable_has_many_through_reflection
|
|
||||||
error = assert_raises(NotImplementedError) { Subscriber.new.published_books }
|
|
||||||
assert_equal <<~MSG.squish, error.message
|
|
||||||
In order to correctly type cast Subscriber.nick,
|
|
||||||
PublishedBook needs to define a :subscriptions association.
|
|
||||||
MSG
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_chain
|
def test_chain
|
||||||
expected = [
|
expected = [
|
||||||
Organization.reflect_on_association(:author_essay_categories),
|
Organization.reflect_on_association(:author_essay_categories),
|
||||||
|
@ -524,3 +516,64 @@ class ReflectionTest < ActiveRecord::TestCase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class UncastableReflectionTest < ActiveRecord::TestCase
|
||||||
|
class Book < ActiveRecord::Base
|
||||||
|
end
|
||||||
|
|
||||||
|
class Subscription < ActiveRecord::Base
|
||||||
|
belongs_to :subscriber
|
||||||
|
belongs_to :book
|
||||||
|
end
|
||||||
|
|
||||||
|
class Subscriber < ActiveRecord::Base
|
||||||
|
self.primary_key = "nick"
|
||||||
|
has_many :subscriptions
|
||||||
|
has_one :subscription
|
||||||
|
has_many :books, through: :subscriptions
|
||||||
|
has_one :book, through: :subscription
|
||||||
|
end
|
||||||
|
|
||||||
|
setup do
|
||||||
|
@subscriber = Subscriber.create!(nick: "unique")
|
||||||
|
end
|
||||||
|
|
||||||
|
teardown do
|
||||||
|
Book._reflections.clear
|
||||||
|
Book.clear_reflections_cache
|
||||||
|
Subscriber.has_many :books, through: :subscriptions
|
||||||
|
Subscriber.has_one :book, through: :subscription
|
||||||
|
end
|
||||||
|
|
||||||
|
test "uncastable has_many through: reflection" do
|
||||||
|
error = assert_raises(NotImplementedError) { @subscriber.books }
|
||||||
|
assert_equal <<~MSG.squish, error.message
|
||||||
|
In order to correctly type cast UncastableReflectionTest::Subscriber.nick,
|
||||||
|
UncastableReflectionTest::Book needs to define a :subscriptions association.
|
||||||
|
MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fixing uncastable has_many through: reflection with has_many" do
|
||||||
|
Book.has_many :subscriptions
|
||||||
|
@subscriber.books
|
||||||
|
end
|
||||||
|
|
||||||
|
test "uncastable has_one through: reflection" do
|
||||||
|
error = assert_raises(NotImplementedError) { @subscriber.book }
|
||||||
|
|
||||||
|
assert_equal <<~MSG.squish, error.message
|
||||||
|
In order to correctly type cast UncastableReflectionTest::Subscriber.nick,
|
||||||
|
UncastableReflectionTest::Book needs to define a :subscription association.
|
||||||
|
MSG
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fixing uncastable has_one through: reflection with has_many" do
|
||||||
|
Book.has_many :subscriptions
|
||||||
|
@subscriber.book
|
||||||
|
end
|
||||||
|
|
||||||
|
test "fixing uncastable has_one through: reflection with has_one" do
|
||||||
|
Book.has_one :subscription
|
||||||
|
@subscriber.book
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue