Skip to content

Commit 5cbf615

Browse files
authored
Merge pull request rails#47541 from Shopify/has-many-through-assign-with-query-constraints
Support assignments for composite key has_many through associations
2 parents 7d7ed37 + bd93237 commit 5cbf615

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

activerecord/lib/active_record/associations/has_many_through_association.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,12 @@ def build_through_record(record)
7070

7171
def through_scope_attributes
7272
scope = through_scope || self.scope
73-
scope.where_values_hash(through_association.reflection.name.to_s).
74-
except!(through_association.reflection.foreign_key,
75-
through_association.reflection.klass.inheritance_column)
73+
attributes = scope.where_values_hash(through_association.reflection.name.to_s)
74+
except_keys = [
75+
*Array(through_association.reflection.foreign_key),
76+
through_association.reflection.klass.inheritance_column
77+
]
78+
attributes.except!(*except_keys)
7679
end
7780

7881
def save_through_record(record)

activerecord/test/cases/associations_test.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,27 @@ def test_assign_composite_foreign_key_belongs_to_association_with_autosave
231231
assert_equal(another_blog.id, comment.blog_id)
232232
assert_equal(comment.blog_post_id, blog_post.id)
233233
end
234+
235+
def test_append_composite_has_many_through_association
236+
blog_post = sharded_blog_posts(:great_post_blog_one)
237+
tag = Sharded::Tag.new(name: "Ruby on Rails", blog_id: blog_post.blog_id)
238+
tag.save
239+
240+
blog_post.tags << tag
241+
242+
assert_includes(blog_post.reload.tags, tag)
243+
assert_predicate Sharded::BlogPostTag.where(blog_post_id: blog_post.id, blog_id: blog_post.blog_id, tag_id: tag.id), :exists?
244+
end
245+
246+
def test_append_composite_has_many_through_association_with_autosave
247+
blog_post = sharded_blog_posts(:great_post_blog_one)
248+
tag = Sharded::Tag.new(name: "Ruby on Rails", blog_id: blog_post.blog_id)
249+
250+
blog_post.tags << tag
251+
252+
assert_includes(blog_post.reload.tags, tag)
253+
assert_predicate Sharded::BlogPostTag.where(blog_post_id: blog_post.id, blog_id: blog_post.blog_id, tag_id: tag.id), :exists?
254+
end
234255
end
235256

236257
class AssociationProxyTest < ActiveRecord::TestCase

0 commit comments

Comments
 (0)