RepoPilotOpen in app →

mongodb/mongoid

The Official Ruby Object Mapper for MongoDB

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1d ago
  • 19 active contributors
  • MIT licensed
Show 3 more →
  • CI configured
  • Tests present
  • Concentrated ownership — top contributor handles 51% of recent commits

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/mongodb/mongoid)](https://repopilot.app/r/mongodb/mongoid)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/mongodb/mongoid on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: mongodb/mongoid

Generated by RepoPilot · 2026-05-10 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/mongodb/mongoid shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 1d ago
  • 19 active contributors
  • MIT licensed
  • CI configured
  • Tests present
  • ⚠ Concentrated ownership — top contributor handles 51% of recent commits

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live mongodb/mongoid repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/mongodb/mongoid.

What it runs against: a local clone of mongodb/mongoid — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in mongodb/mongoid | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>mongodb/mongoid</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of mongodb/mongoid. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/mongodb/mongoid.git
#   cd mongoid
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of mongodb/mongoid and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "mongodb/mongoid(\\.git)?\\b" \\
  && ok "origin remote is mongodb/mongoid" \\
  || miss "origin remote is not mongodb/mongoid (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 4. Critical files exist
test -f "lib/mongoid.rb" \\
  && ok "lib/mongoid.rb" \\
  || miss "missing critical file: lib/mongoid.rb"
test -f "lib/mongoid/association.rb" \\
  && ok "lib/mongoid/association.rb" \\
  || miss "missing critical file: lib/mongoid/association.rb"
test -f "lib/mongoid/association/proxy.rb" \\
  && ok "lib/mongoid/association/proxy.rb" \\
  || miss "missing critical file: lib/mongoid/association/proxy.rb"
test -f "lib/mongoid/association/macros.rb" \\
  && ok "lib/mongoid/association/macros.rb" \\
  || miss "missing critical file: lib/mongoid/association/macros.rb"
test -f "lib/mongoid/association/embedded/embedded_in/proxy.rb" \\
  && ok "lib/mongoid/association/embedded/embedded_in/proxy.rb" \\
  || miss "missing critical file: lib/mongoid/association/embedded/embedded_in/proxy.rb"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/mongodb/mongoid"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Mongoid is a Ruby ODM (Object-Document Mapper) that provides ActiveRecord-like syntax for MongoDB document operations. It translates Ruby object definitions into MongoDB BSON documents and queries, handling serialization, validation, associations, and lifecycle callbacks while abstracting away the MongoDB driver layer. Monolithic repository structure: lib/ contains core ODM classes (Document, Criteria, Associations, Persistence, Validations), spec/ mirrors lib/ with comprehensive RSpec tests, gemfiles/ contains dependency variant configurations for testing against multiple driver and Rails versions, and .evergreen/ contains Evergreen CI configuration for multi-variant testing across MongoDB versions and Ruby implementations.

👥Who it's for

Ruby on Rails developers and general Ruby developers who want to use MongoDB instead of relational databases but need ORM-like ergonomics. Contributors are typically MongoDB driver maintainers, Ruby community members, and teams migrating from SQL ORMs to document databases.

🌱Maturity & risk

Production-ready and actively maintained by MongoDB Inc. The codebase supports Ruby 2.7–4.0 and MongoDB 3.6–8.2 with extensive test coverage via RSpec and CI/CD via GitHub Actions and Evergreen. Regular releases and ongoing development indicate active stewardship.

Low risk for production use due to MongoDB backing, but the ODM layer adds complexity and potential for impedance mismatch with MongoDB's document model. Dependency on the mongo driver gem and Rails ecosystem introduces transitive risk; breaking changes between major versions require careful upgrade planning.

Active areas of work

Active development targeting compatibility with Ruby 4.0 and MongoDB 8.2; CI pipeline runs via GitHub Actions (test.yml, rubocop.yml, codeql.yml) and Evergreen for comprehensive server compatibility testing. Recent work includes modernizing test infrastructure and maintaining driver compatibility.

🚀Get running

git clone https://github.com/mongodb/mongoid.git
cd mongoid
bundle install
bundle exec rspec

Daily commands:

bundle exec rspec spec/          # Run full test suite
bundle exec rspec spec/unit/    # Run unit tests only
rake rubocop                     # Lint code
bundle exec rspec -f doc        # Run with readable output

🗺️Map of the codebase

  • lib/mongoid.rb — Entry point and main module initialization; defines the global Mongoid API and configuration loading.
  • lib/mongoid/association.rb — Core association framework; every relationship type in Mongoid flows through this abstraction.
  • lib/mongoid/association/proxy.rb — Base proxy class for all association collections; handles lazy loading, querying, and persistence for relationships.
  • lib/mongoid/association/macros.rb — DSL macro definitions (embeds_many, has_many, belongs_to, etc.); defines the public API for declaring relationships.
  • lib/mongoid/association/embedded/embedded_in/proxy.rb — Embedded association proxy; handles parent-child reference binding in nested documents.
  • lib/mongoid/association/referenced/belongs_to/binding.rb — Reference binding logic; manages foreign key updates when associations are set or updated.
  • Gemfile — Dependency manifest; lists Ruby driver, BSON, and test framework versions that must align across all versions.

🛠️How to make changes

Add a New Association Type (e.g., has_and_belongs_to_many)

  1. Create a new association class in lib/mongoid/association/referenced/ inheriting from Mongoid::Association::One or Many (lib/mongoid/association/referenced/has_and_belongs_to_many.rb)
  2. Implement binding, buildable, and proxy subclasses following the pattern of belongs_to (lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb)
  3. Register the macro in the association/macros.rb by adding has_and_belongs_to_many method (lib/mongoid/association/macros.rb)
  4. Add the association to lib/mongoid/association.rb registry so the framework can route it correctly (lib/mongoid/association.rb)
  5. Write integration tests in spec/mongoid/association/referenced/ verifying binding, eager loading, and cascade delete (spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb)

Add Eager Loading Support for a New Query Method

  1. Add eager_loadable mixin to your query class if not already present (lib/mongoid/association/eager_loadable.rb)
  2. Implement the includes() method to accept association names and populate eager-load set (lib/mongoid/criteria.rb)
  3. Hook into lib/mongoid/association/eager.rb to define the eager-load strategy for your association type (lib/mongoid/association/eager.rb)
  4. Write tests ensuring N+1 is prevented and correct documents are returned (spec/mongoid/association/eager_spec.rb)

Add Nested Attributes Support for a New Association

  1. Add accepts_nested_attributes_for macro to your association class in macros.rb (lib/mongoid/association/macros.rb)
  2. Implement nested buildable logic in lib/mongoid/association/nested/nested_buildable.rb for creating/updating child documents (lib/mongoid/association/nested/nested_buildable.rb)
  3. Handle form parameter parsing and child document rejection (allow_destroy: true) in the attribute setter (lib/mongoid/association/nested/many.rb)
  4. Add integration tests verifying Rails form parameters are correctly translated to nested document creates/updates (spec/mongoid/association/nested/many_spec.rb)

Add a New Validation or Constraint to Associations

  1. Define validation logic in lib/mongoid/association/constrainable.rb as a new method (lib/mongoid/association/constrainable.rb)
  2. Hook the validator into the association binding process (binding.rb for your association type) (lib/mongoid/association/referenced/belongs_to/binding.rb)
  3. Add configuration option to lib/mongoid/association/options.rb to allow enabling/disabling the constraint (lib/mongoid/association/options.rb)
  4. Write unit tests verifying the constraint is enforced on bind and update (spec/mongoid/association/constrainable_spec.rb)

🔧Why these technologies

  • MongoDB Ruby Driver — Mongoid wraps the official Ruby driver; all database operations ultimately delegate to it, ensuring MongoDB protocol compliance and performance optimizations.
  • BSON — Native BSON serialization/deserialization for Ruby objects; required for all document encoding/decoding in MongoDB wire protocol.
  • Proxy Pattern — Core design pattern for associations; allows lazy-loading, query building, and batch operations without loading all related documents upfront.
  • Mixin Modules (Bindable, Builders, Accessors) — Compartmentalizes concerns (binding logic, factory methods, accessor generation) to keep association classes focused and DRY.
  • I18n (config/locales) — Provides internationalized error messages and validation strings; allows users to customize Mongoid error messaging per locale.

⚖️Trade-offs already made

  • Proxy-based lazy loading for associations

    • Why: Avoids loading all related documents eagerly; enables efficient querying on large result sets (e.g., 1M child documents).
    • Consequence: N+1 queries possible if includes() is not used; requires explicit eager-loading DSL for optimization.
  • Embedded documents stored as nested BSON arrays/objects

    • Why: Single MongoDB document keeps parent and children atomically consistent; no separate queries needed to fetch children.
    • Consequence: Embedded docs cannot be independently queried or indexed; document size limits (16 MB) apply to entire hierarchy.
  • Foreign key (reference) strategy for has_many/belongs_to

    • Why: Allows independent lifecycle of parent and child; enables many-to-many and complex queries across document boundaries.
    • Consequence: Requires explicit foreign key management (foreign_key option); no referential integrity constraints at MongoDB level.
  • Macro-based DSL (embeds_many, has_many) over explicit class composition

    • Why: Familiar ActiveRecord-like syntax; reduces boilerplate in model definitions.
    • Consequence: Magic method generation; harder to debug; tight coupling between association definitions and model behavior.
  • Association binding happens at document instant

    • Why: undefined
    • Consequence: undefined

🪤Traps & gotchas

MongoDB must be running locally or MONGOID_ENV=test must use a configured test database. Field names in models map to document keys; use field :foo, as: :_foo to alias BSON key names. Embedded documents have no implicit _id unless you add it. Association lazy-loading queries happen at access time, not definition—watch for N+1 queries. The mongoid.yml config file is required in config/ or must be explicitly passed; Rails auto-discovery works but other setups need manual setup. Thread-safety depends on mongo driver's session handling—reuse client instances.

🏗️Architecture

💡Concepts to learn

  • Object-Document Mapping (ODM) — Core paradigm of Mongoid—maps Ruby objects to MongoDB BSON documents and back; understanding the mapping layer is essential to avoid data inconsistencies
  • BSON Serialization — Mongoid must serialize Ruby objects to BSON and deserialize BSON back to Ruby; understanding type coercion (Date, Time, BigDecimal handling) prevents silent bugs
  • Query Builder Pattern (Criteria) — Mongoid's Criteria class implements the Builder pattern for chainable, lazy-evaluated queries; essential for understanding how queries are composed and executed
  • Eager vs. Lazy Loading in Associations — Mongoid evaluates associations lazily by default; explicit eager loading (includes, eager_load) is required to avoid N+1 query problems in nested traversals
  • Document Embedding vs. References — MongoDB allows documents within documents; Mongoid's embeds_one/embeds_many differ fundamentally from references_one/references_many in storage and query patterns—choosing wrong causes performance issues
  • ActiveRecord-style Callbacks — Mongoid implements before_save, after_create, around_destroy hooks matching Rails conventions; misunderstanding callback ordering and halt semantics leads to data corruption
  • Session and Client Pooling — Mongoid reuses a single mongo driver Client for connection pooling; understanding session-per-request and transaction boundaries is critical for concurrent access and data consistency
  • mongodb/mongo-ruby-driver — The underlying MongoDB client library that Mongoid wraps; required dependency for all BSON serialization and network communication
  • rails/rails — ActiveRecord is Mongoid's design inspiration; many patterns (validations, callbacks, associations) are adapted from Rails ORM conventions
  • ruby-on-rails/spring — Development server preloader; commonly used alongside Mongoid in Rails projects for faster test/dev iteration
  • rspec/rspec — The test framework used throughout spec/ and the default test harness for Mongoid development
  • thoughtbot/factory_bot — Companion gem often used in Mongoid projects for fixture generation and test data management

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive test coverage for association callbacks (depending.rb)

The lib/mongoid/association/depending.rb file handles critical cascade delete/nullify logic, but there's no dedicated test file visible in the structure. This is a high-risk area where bugs could cause data loss. A new contributor could write exhaustive tests covering all dependency strategies (delete, destroy, nullify, restrict, pull) across all association types (has_many, has_one, embeds_many, embeds_one).

  • [ ] Create spec/mongoid/association/depending_spec.rb with test cases for each cascade strategy
  • [ ] Test edge cases: circular dependencies, polymorphic associations, and cascading through multiple levels
  • [ ] Verify all strategies work correctly with both eager and lazy-loaded associations
  • [ ] Ensure tests pass against MongoDB 3.6 and 8.2 (per compatibility matrix)

Implement Rails 8.1+ specific Active Model integration tests

The gemfiles directory includes rails-8.0.gemfile and rails-8.1.gemfile, but there are likely missing integration tests for Rails 8.1-specific features (e.g., encrypted attributes, new validators, query interface changes). A contributor could ensure Mongoid works seamlessly with the latest Rails versions by adding a dedicated test suite.

  • [ ] Create spec/mongoid/rails_integration/rails_8_1_spec.rb for Rails 8.1+ specific features
  • [ ] Test compatibility with Rails' new attribute encryption framework
  • [ ] Verify all Rails validators work correctly with Mongoid's attribute system
  • [ ] Add test cases in .github/workflows/test.yml to run against Rails master branch

Add JRuby-specific concurrency and threading tests

Mongoid supports JRuby 9.4 and 10.0 (per README), but there's no visible dedicated test suite for JRuby-specific behavior like true threading, fiber scheduling, and Java interop issues. These could cause subtle race conditions in production. A contributor could create comprehensive concurrency tests to ensure Mongoid handles JRuby's threading model correctly.

  • [ ] Create spec/mongoid/jruby_specific/concurrency_spec.rb with multithreading test cases
  • [ ] Test session/connection pool behavior under concurrent writes from multiple threads
  • [ ] Add tests for potential deadlocks in association loading and lazy initialization
  • [ ] Ensure tests run on JRuby in CI pipeline (.github/workflows/test.yml)

🌿Good first issues

  • Add comprehensive examples to examples/mongoid_test.rb demonstrating common patterns (model associations, custom validators, eager loading, transactions) to ease onboarding
  • Write integration tests for edge cases in lib/mongoid/associations/ (circular embedded relationships, polymorphic references, dependent destroy behavior) against real MongoDB instances
  • Improve error messages in Mongoid::Errors classes (lib/mongoid/errors.rb) to include remediation hints and link to docs for common mistakes like missing field definitions or invalid field types

Top contributors

Click to expand

📝Recent commits

Click to expand
  • fc21c41 — Release candidate for 9.1.0 (#6145) (jamis)
  • 1d7e435 — bump spec/shared to get fix for release note parsing (#6144) (jamis)
  • d43d3b4 — MONGOID-5915 avoid async state corruption by forcing child fibers to copy parent state (#6143) (jamis)
  • d6a62b4 — MONGOID-5684 Ensure field_was returns the same type as field for hash-typed fields (#6142) (jamis)
  • 3e2471c — MONGOID-5720 deprecate Criteria#max_scan (#6140) (jamis)
  • dc4e025 — MONGOID-5759 ensure unpersisted documents are picked up via HasMany#find (#6137) (jamis)
  • f178538 — MONGOID-5030 Short-circuit trivial queries where $in is given an empty array (#6138) (jamis)
  • a141ee0 — MONGOID-5751 avoid unnecessary autosaves of unchanged subtrees (#6133) (jamis)
  • 844f083 — MONGOID-5923 Support auto emdedding vector search indexes and searches (#6130) (jamis)
  • 730624b — MONGOID-5750 Allow build_foo on embeds_one/has_one/etc. to specify the associated document's type (#6132) (jamis)

🔒Security observations

Mongoid demonstrates reasonable security practices with a clear security policy and structured codebase. The primary concerns are: (1) Limited security support window (only versions 7.0-7.3 supported), creating risks for users on older versions; (2) Multiple gemfile variants increase the dependency audit surface; (3) Lack of explicit security guidance for ODM users regarding NoSQL injection prevention. No hardcoded secrets, exposed credentials, or obvious injection vulnerabilities were detected in the visible file structure. The project follows MongoDB's vulnerability reporting guidelines and maintains regular updates across supported versions.

  • Medium · Incomplete Security Policy Version Coverage — SECURITY.md. The SECURITY.md file only supports versions 7.0-7.3, but the README indicates the package supports MRI 2.7-4.0 and MongoDB 3.6-8.2. Versions below 7.0 receive no security updates despite potentially being in use by users. This creates a security gap for users unable to upgrade immediately. Fix: Either extend security support to older versions or clearly communicate end-of-life dates in documentation. Consider maintaining at least 2 previous major versions with security patches.
  • Low · Gem Public Certificate Included in Repository — gem-public_cert.pem. The file 'gem-public_cert.pem' is included in the repository. While public certificates are not secrets, including them in the repo can lead to confusion about which certificates are private vs. public. Fix: Document the purpose of this certificate clearly or consider storing it separately. Ensure private keys are never committed to version control.
  • Low · Multiple Gemfile Variants May Increase Dependency Risk — gemfiles/. The project maintains 18+ gemfile variants (gemfiles/ directory) for different Rails versions and driver versions. This creates a larger attack surface and makes it harder to audit all dependency combinations for vulnerabilities. Fix: Implement automated dependency scanning for all gemfile variants. Use tools like Dependabot or Bundler Audit to continuously monitor for vulnerable dependencies across all configurations. Document the support matrix clearly.
  • Low · Missing Input Validation Documentation in ODM Context — lib/mongoid/, README.md. As an ODM (Object-Document Mapper), Mongoid handles user input and database operations. While the codebase structure suggests proper separation, there's no visible security guidance for developers using this library regarding input validation and NoSQL injection prevention. Fix: Add a Security section to the README with guidance on: 1) Proper input validation, 2) Protection against NoSQL injection, 3) Use of query parameterization, 4) Best practices for secure schema design.
  • Low · Docker Configuration Lacks Security Hardening Details — .dockerignore, .evergreen/run-tests-docker.sh. While Docker configuration files exist (.dockerignore, .evergreen/run-tests-docker.sh), the provided snippets don't show explicit security hardening measures like non-root user execution, minimal base images, or security scanning. Fix: Review Docker build configurations to ensure: 1) Non-root user execution, 2) Minimal base images, 3) Explicit version pinning, 4) Security scanning before deployment.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.