From 620f837244eaa20576c0244bb3dcbd00ca8ad1f1 Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Thu, 23 Apr 2026 11:32:53 -0600 Subject: [PATCH] MONGOID-5759 ensure unpersisted documents are picked up via HasMany#find --- .../association/referenced/has_many/proxy.rb | 12 ++++++++---- .../referenced/has_many/proxy_spec.rb | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/lib/mongoid/association/referenced/has_many/proxy.rb b/lib/mongoid/association/referenced/has_many/proxy.rb index 23576873a8..fc1f3efc58 100644 --- a/lib/mongoid/association/referenced/has_many/proxy.rb +++ b/lib/mongoid/association/referenced/has_many/proxy.rb @@ -259,10 +259,14 @@ def exists?(id_or_conditions = :none) # @yield [ Object ] Yields each enumerable element to the block. # # @return [ Document | Array | nil ] A document or matching documents. - def find(...) - matching = criteria.find(...) - Array(matching).each { |doc| _target.push(doc) } - matching + def find(*args, &block) + if block_given? && args.empty? + detect(&block) + else + matching = criteria.find(*args, &block) + Array(matching).each { |doc| _target.push(doc) } + matching + end end # Removes all associations between the base document and the target diff --git a/spec/mongoid/association/referenced/has_many/proxy_spec.rb b/spec/mongoid/association/referenced/has_many/proxy_spec.rb index 1b8e2fa36d..fdd853d590 100644 --- a/spec/mongoid/association/referenced/has_many/proxy_spec.rb +++ b/spec/mongoid/association/referenced/has_many/proxy_spec.rb @@ -2246,6 +2246,23 @@ def with_transaction_via(model, &block) end ).to be_nil end + + context 'when the parent is not persisted (MONGOID-5759)' do + let(:person) { Person.new } + let!(:post) { person.posts.build(title: 'unpersisted post') } + + it 'yields unpersisted built documents' do + expect( + person.posts.find { |p| p.title == 'unpersisted post' } + ).to eq(post) + end + + it 'returns nil when no match among unpersisted documents' do + expect( + person.posts.find { |p| p.title == 'other' } + ).to be_nil + end + end end end