Skip to content

Commit 4bcf7e5

Browse files
committed
Handle polymorphic collection associations when setting through records
1 parent 6df15e2 commit 4bcf7e5

File tree

3 files changed

+40
-2
lines changed

3 files changed

+40
-2
lines changed

activerecord/lib/active_record/associations/collection_association.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ def load_target
279279
if middle_target.nil? || (middle_reflection.collection? && middle_target.empty?)
280280
break []
281281
elsif middle_reflection.collection?
282-
middle_target.flat_map { |record| record.association(through_reflection.source_reflection_name).load_target }
282+
middle_target.flat_map { |record| record.association(through_reflection.source_reflection_name).load_target }.compact
283283
else
284284
middle_target.association(through_reflection.source_reflection_name).load_target
285285
end

activerecord/lib/active_record/reflection.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1235,7 +1235,7 @@ def derive_class_name
12351235

12361236
class PolymorphicReflection < AbstractReflection # :nodoc:
12371237
delegate :klass, :scope, :plural_name, :type, :join_primary_key, :join_foreign_key,
1238-
:name, :scope_for, to: :@reflection
1238+
:name, :scope_for, :collection?, to: :@reflection
12391239

12401240
def initialize(reflection, previous_reflection)
12411241
super()

activerecord/test/cases/associations/has_many_through_associations_test.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,44 @@ def test_setting_has_many_through_many_association_on_new_record_sets_through_re
8484
assert_no_queries { assert_equal [subscriber_1, subscriber_2].sort, book.subscribers.sort }
8585
end
8686

87+
def test_setting_has_many_through_many_association_with_missing_targets_on_new_record_sets_empty_through_records
88+
subscription_1 = Subscription.new
89+
subscription_2 = Subscription.new
90+
book = Book.new
91+
book.subscriptions = [subscription_1, subscription_2]
92+
93+
assert_predicate book, :new_record?
94+
book.subscriptions.each { |subscription| assert_predicate subscription, :new_record? }
95+
assert_no_queries { assert_equal [], book.subscribers }
96+
end
97+
98+
def test_setting_has_many_through_many_association_with_partial_missing_targets_on_new_record_sets_partial_through_records
99+
subscriber_1 = Subscriber.create!(nick: "nick 1")
100+
subscription_1 = Subscription.new(subscriber: subscriber_1)
101+
subscription_2 = Subscription.new
102+
book = Book.new
103+
book.subscriptions = [subscription_1, subscription_2]
104+
105+
assert_predicate subscriber_1, :persisted?
106+
assert_predicate book, :new_record?
107+
book.subscriptions.each { |subscription| assert_predicate subscription, :new_record? }
108+
assert_no_queries { assert_equal [subscriber_1], book.subscribers }
109+
end
110+
111+
def test_setting_polymorphic_has_many_through_many_association_on_new_record_sets_through_records
112+
human_1, human_2 = Human.create!, Human.create!
113+
interest_1 = Interest.new(polymorphic_human: human_1)
114+
interest_2 = Interest.new(polymorphic_human: human_2)
115+
zine = Zine.new
116+
zine.interests = [interest_1, interest_2]
117+
118+
assert_predicate human_1, :persisted?
119+
assert_predicate human_2, :persisted?
120+
assert_predicate zine, :new_record?
121+
zine.interests.each { |interest| assert_predicate interest, :new_record? }
122+
assert_no_queries { assert_equal [human_1, human_2].sort, zine.polymorphic_humans.sort }
123+
end
124+
87125
def test_setting_nested_has_many_through_one_association_on_new_record_sets_nested_through_records
88126
post_tagging_1, post_tagging_2 = Tagging.create!, Tagging.create!
89127
post = Post.create!(title: "Tagged", body: "Post", taggings: [post_tagging_1, post_tagging_2])

0 commit comments

Comments
 (0)