Skip to content

Commit 19b1894

Browse files
authored
Merge pull request rails#48124 from Shopify/use-read-attribute-instead-public-reader-in-association-preloader
Use `_read_attribute` in associations preloader instead of public reader
2 parents d21c0f5 + 91dad14 commit 19b1894

File tree

2 files changed

+50
-3
lines changed

2 files changed

+50
-3
lines changed

activerecord/lib/active_record/associations/preloader/association.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,9 +252,9 @@ def key_conversion_required?
252252

253253
def derive_key(owner, key)
254254
if key.is_a?(Array)
255-
key.map { |k| convert_key(owner[k]) }
255+
key.map { |k| convert_key(owner._read_attribute(k)) }
256256
else
257-
convert_key(owner[key])
257+
convert_key(owner._read_attribute(key))
258258
end
259259
end
260260

activerecord/test/cases/associations_test.rb

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -688,7 +688,7 @@ def test_associations_raise_with_name_error_if_associated_to_classes_that_do_not
688688
class PreloaderTest < ActiveRecord::TestCase
689689
fixtures :posts, :comments, :books, :authors, :tags, :taggings, :essays, :categories, :author_addresses,
690690
:sharded_blog_posts, :sharded_comments, :sharded_blog_posts_tags, :sharded_tags,
691-
:members, :member_details, :organizations
691+
:members, :member_details, :organizations, :cpk_orders, :cpk_order_agreements
692692

693693
def test_preload_with_scope
694694
post = posts(:welcome)
@@ -1328,6 +1328,53 @@ def test_preload_has_many_through_association_with_composite_query_constraints
13281328

13291329
assert_equal(expected_blog_post_ids.sort, tag.blog_posts.map(&:id).sort)
13301330
end
1331+
1332+
def test_preloads_has_many_on_model_with_a_composite_primary_key_through_id_attribute
1333+
order = cpk_orders(:cpk_groceries_order_2)
1334+
_shop_id, order_id = order.id
1335+
order_agreements = Cpk::OrderAgreement.where(order_id: order_id).to_a
1336+
1337+
assert_not_empty order_agreements
1338+
assert_equal order_agreements.sort, order.order_agreements.sort
1339+
1340+
loaded_order = nil
1341+
sql = capture_sql do
1342+
loaded_order = Cpk::Order.where(id: order_id).includes(:order_agreements).to_a.first
1343+
end
1344+
1345+
assert_equal 2, sql.size
1346+
preload_sql = sql.last
1347+
1348+
c = Cpk::OrderAgreement.connection
1349+
order_id_column = Regexp.escape(c.quote_table_name("cpk_order_agreements.order_id"))
1350+
order_id_constraint = /#{order_id_column} = (\?|(\d+)|\$\d)$/
1351+
expectation = /SELECT.*WHERE.* #{order_id_constraint}/
1352+
1353+
assert_match(expectation, preload_sql)
1354+
assert_equal order_agreements.sort, loaded_order.order_agreements.sort
1355+
end
1356+
1357+
def test_preloads_belongs_to_a_composite_primary_key_model_through_id_attribute
1358+
order_agreement = cpk_order_agreements(:order_agreement_three)
1359+
order = cpk_orders(:cpk_groceries_order_2)
1360+
assert_equal order, order_agreement.order
1361+
1362+
loaded_order_agreement = nil
1363+
sql = capture_sql do
1364+
loaded_order_agreement = Cpk::OrderAgreement.where(id: order_agreement.id).includes(:order).to_a.first
1365+
end
1366+
1367+
assert_equal 2, sql.size
1368+
preload_sql = sql.last
1369+
1370+
c = Cpk::Order.connection
1371+
order_id = Regexp.escape(c.quote_table_name("cpk_orders.id"))
1372+
order_constraint = /#{order_id} = (\?|(\d+)|\$\d)$/
1373+
expectation = /SELECT.*WHERE.* #{order_constraint}/
1374+
1375+
assert_match(expectation, preload_sql)
1376+
assert_equal order, loaded_order_agreement.order
1377+
end
13311378
end
13321379

13331380
class GeneratedMethodsTest < ActiveRecord::TestCase

0 commit comments

Comments
 (0)