Skip to content

Commit f1b923b

Browse files
authored
Merge pull request rails#41090 from kamipo/fix_find_by_with_custom_primary_key
Fix `find_by` with custom primary key for belongs_to association
2 parents 8632a53 + 6f8fca8 commit f1b923b

File tree

2 files changed

+26
-16
lines changed

2 files changed

+26
-16
lines changed

activerecord/lib/active_record/core.rb

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -332,31 +332,37 @@ def find_by(*args) # :nodoc:
332332
hash = args.first
333333
return super unless Hash === hash
334334

335-
values = hash.values.map! { |value| value.respond_to?(:id) ? value.id : value }
336-
return super if values.any? { |v| StatementCache.unsupported_value?(v) }
337-
338-
keys = hash.keys.map! do |key|
339-
attribute_aliases[name = key.to_s] || begin
340-
reflection = _reflect_on_association(name)
341-
if reflection&.belongs_to? && !reflection.polymorphic?
342-
reflection.join_foreign_key
343-
elsif reflect_on_aggregation(name)
344-
return super
345-
else
346-
name
347-
end
335+
hash = hash.each_with_object({}) do |(key, value), h|
336+
key = key.to_s
337+
key = attribute_aliases[key] || key
338+
339+
return super if reflect_on_aggregation(key)
340+
341+
reflection = _reflect_on_association(key)
342+
343+
if !reflection
344+
value = value.id if value.respond_to?(:id)
345+
elsif reflection.belongs_to? && !reflection.polymorphic?
346+
key = reflection.join_foreign_key
347+
pkey = reflection.join_primary_key
348+
value = value.public_send(pkey) if value.respond_to?(pkey)
349+
end
350+
351+
if !columns_hash.key?(key) || StatementCache.unsupported_value?(value)
352+
return super
348353
end
349-
end
350354

351-
return super unless keys.all? { |k| columns_hash.key?(k) }
355+
h[key] = value
356+
end
352357

358+
keys = hash.keys
353359
statement = cached_find_by_statement(keys) { |params|
354360
wheres = keys.index_with { params.bind }
355361
where(wheres).limit(1)
356362
}
357363

358364
begin
359-
statement.execute(values, connection).first
365+
statement.execute(hash.values, connection).first
360366
rescue TypeError
361367
raise ActiveRecord::StatementInvalid
362368
end

activerecord/test/cases/associations/belongs_to_associations_test.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ def test_where_with_custom_primary_key
4646
assert_equal [authors(:david)], Author.where(owned_essay: essays(:david_modest_proposal))
4747
end
4848

49+
def test_find_by_with_custom_primary_key
50+
assert_equal authors(:david), Author.find_by(owned_essay: essays(:david_modest_proposal))
51+
end
52+
4953
def test_where_on_polymorphic_association_with_nil
5054
assert_equal comments(:greetings), Comment.where(author: nil).first
5155
assert_equal comments(:greetings), Comment.where(author: [nil]).first

0 commit comments

Comments
 (0)