Skip to content

Commit 95a3e6c

Browse files
committed
Allow querying by whole record for composite query constraints associations
Given an association defined with composite query constraints like: ```ruby BlogPost.has_many :comments, query_constraints: [:blog_id, :blog_post_id] ``` it is possible to query blog posts by whole `comments` objects like: ```ruby comments = Comment.first(2) BlogPost.where(comments: comments).to_a ```
1 parent 2109326 commit 95a3e6c

File tree

3 files changed

+17
-2
lines changed

3 files changed

+17
-2
lines changed

activerecord/lib/active_record/relation/predicate_builder/association_query_value.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,11 @@ def initialize(associated_table, value)
99
end
1010

1111
def queries
12-
[ associated_table.join_foreign_key => ids ]
12+
if associated_table.join_foreign_key.is_a?(Array)
13+
ids.map { |ids_set| associated_table.join_foreign_key.zip(ids_set).to_h }
14+
else
15+
[ associated_table.join_foreign_key => ids ]
16+
end
1317
end
1418

1519
private
@@ -31,6 +35,8 @@ def primary_key
3135
end
3236

3337
def convert_to_id(value)
38+
return primary_key.map { |pk| value.public_send(pk) } if primary_key.is_a?(Array)
39+
3440
if value.respond_to?(primary_key)
3541
value.public_send(primary_key)
3642
else

activerecord/test/cases/associations_test.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,15 @@ def test_belongs_to_a_model_with_composite_primary_key_uses_composite_pk_in_sql
147147
assert_match(/#{Regexp.escape(Sharded::BlogPost.connection.quote_table_name("sharded_blog_posts.id"))} =/, sql)
148148
end
149149

150+
def test_querying_by_whole_associated_records_using_query_constraints
151+
comments = [sharded_comments(:great_comment_blog_post_one), sharded_comments(:great_comment_blog_post_two)]
152+
153+
blog_posts = Sharded::BlogPost.where(comments: comments).to_a
154+
155+
expected_posts = [sharded_blog_posts(:great_post_blog_one), sharded_blog_posts(:great_post_blog_two)]
156+
assert_equal(expected_posts.map(&:id).sort, blog_posts.map(&:id).sort)
157+
end
158+
150159
def test_has_many_association_with_composite_foreign_key_loads_records
151160
blog_post = sharded_blog_posts(:great_post_blog_one)
152161

activerecord/test/fixtures/sharded_comments.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,5 @@ unique_comment_blog_post_one:
1818

1919
great_comment_blog_post_two:
2020
body: "I really enjoyed the post!"
21-
blog_post_id: <%= ActiveRecord::FixtureSet.identify(:great_blog_post_two) %>
21+
blog_post_id: <%= ActiveRecord::FixtureSet.identify(:great_post_blog_two) %>
2222
blog_id: <%= ActiveRecord::FixtureSet.identify(:sharded_blog_two) %>

0 commit comments

Comments
 (0)