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