Skip to content

MONGOID-5759 ensure unpersisted documents are picked up via HasMany#find#6137

Merged
jamis merged 1 commit intomongodb:masterfrom
jamis:5759-enumerations-yield
Apr 24, 2026
Merged

MONGOID-5759 ensure unpersisted documents are picked up via HasMany#find#6137
jamis merged 1 commit intomongodb:masterfrom
jamis:5759-enumerations-yield

Conversation

@jamis
Copy link
Copy Markdown
Contributor

@jamis jamis commented Apr 23, 2026

When using find with a block on a has-many association, Mongoid does not include unpersisted documents in the search. This PR fixes that bug.

Copilot AI review requested due to automatic review settings April 23, 2026 17:35
@jamis jamis requested a review from a team as a code owner April 23, 2026 17:35
@jamis jamis requested a review from comandeo-mongo April 23, 2026 17:35
@jamis jamis added the bug Fixes a bug, with no new features or broken compatibility label Apr 23, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes HasMany#find with a block so that it searches in-memory (built/unpersisted) associated documents in addition to persisted records, addressing MONGOID-5759.

Changes:

  • Add specs verifying has_many #find { ... } returns built/unpersisted documents when the parent is not persisted.
  • Update HasMany::Proxy#find to use in-memory enumeration (detect) when called with only a block.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
spec/mongoid/association/referenced/has_many/proxy_spec.rb Adds regression coverage for #find with block to include built/unpersisted documents when parent is new.
lib/mongoid/association/referenced/has_many/proxy.rb Adjusts #find behavior for block-only calls to search the association enumerable (including _added docs).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +262 to +269
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
Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Proxy#find handles the common find { ... } case by calling detect, which makes built/unpersisted documents visible. However, Mongoid::Criteria#find (and Ruby's Enumerable#find) also support the optional ifnone Proc argument (find(-> { default }) { ... }). With the current condition (block_given? && args.empty?), that form still delegates to criteria.find and will continue to ignore built/unpersisted documents. Consider matching the same empty_or_proc logic as Mongoid::Findable#find / Criteria#find and calling detect(*args, &block) when a block is given and args are empty or a single Proc.

Copilot uses AI. Check for mistakes.
@jamis jamis merged commit dc4e025 into mongodb:master Apr 24, 2026
80 checks passed
@jamis jamis deleted the 5759-enumerations-yield branch April 24, 2026 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Fixes a bug, with no new features or broken compatibility

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants