diff --git a/docs/.gitignore b/docs/.gitignore
deleted file mode 100644
index e35d8850c9..0000000000
--- a/docs/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-_build
diff --git a/docs/Makefile b/docs/Makefile
deleted file mode 100644
index d4bb2cbb9e..0000000000
--- a/docs/Makefile
+++ /dev/null
@@ -1,20 +0,0 @@
-# Minimal makefile for Sphinx documentation
-#
-
-# You can set these variables from the command line, and also
-# from the environment for the first two.
-SPHINXOPTS ?=
-SPHINXBUILD ?= sphinx-build
-SOURCEDIR = .
-BUILDDIR = _build
-
-# Put it first so that "make" without argument is like "make help".
-help:
- @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
-
-.PHONY: help Makefile
-
-# Catch-all target: route all unknown targets to Sphinx using the new
-# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
-%: Makefile
- @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/README.md b/docs/README.md
deleted file mode 100644
index a3e415face..0000000000
--- a/docs/README.md
+++ /dev/null
@@ -1,14 +0,0 @@
-Mongoid Documentation
-=================================
-
-This subdirectory contains the high-level driver documentation, including
-tutorials and the reference.
-
-To build the documentation locally for review, install `sphinx` and
-`sphinx-book-theme`, then execute `make html` in this directory:
-
- pip install 'sphinx<4.3' sphinx-book-theme
- make html
-
-Note: sphinx 4.3 is currently breaking when trying to render Mongoid
-documentation.
diff --git a/docs/additional-resources.txt b/docs/additional-resources.txt
deleted file mode 100644
index 8de82da599..0000000000
--- a/docs/additional-resources.txt
+++ /dev/null
@@ -1,61 +0,0 @@
-********************
-Additional Resources
-********************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-This page lists some of the third-party guides and blog posts about Mongoid,
-as well as sample Mongoid applications. Additional resources for the driver
-are listed on the `respective driver page
-`_.
-
-
-Screencasts
-===========
-
-- `RailsCasts: Mongoid (revised)
- `_
-
- An overview of Mongoid, by Ryan Bates including the basics
- of setting up an app, querying for documents, adding embedded
- associations, overriding the id, and more.
-
-- `Ruby on Rails Web Services and Integration with MongoDB, Week 3: Mongoid
- `_
-
- A detailed introduction to Mongoid and Ruby on Rails web services.
-
-- `Create a search bar in Rails with Mongoid
- `_
-
- A Tutorial explaining how to implement text search with Mongoid.
-
-
-Articles
-========
-
-- `A Simple Content Management System in Sinatra `_
-
- Building a content management application with Sinatra and Mongoid.
-
-- `How To Create A Ruby API With Sinatra `_
-
- Creating a Sinatra API with Mongoid.
-
-- `Converting an existing Ruby on Rails application to MongoDB `_
-
- How to Convert an existing Ruby on Rails application to use MongoDB and Mongoid.
-
-
-Sample Applications
-===================
-
-- `Mongoid Demo `_
-
- A repository containing sample applications using Mongoid.
diff --git a/docs/conf.py b/docs/conf.py
deleted file mode 100644
index b634583a1a..0000000000
--- a/docs/conf.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Configuration file for the Sphinx documentation builder.
-#
-# This file only contains a selection of the most common options. For a full
-# list see the documentation:
-# https://www.sphinx-doc.org/en/master/usage/configuration.html
-
-# -- Path setup --------------------------------------------------------------
-
-# If extensions (or modules to document with autodoc) are in another directory,
-# add these directories to sys.path here. If the directory is relative to the
-# documentation root, use os.path.abspath to make it absolute, like shown here.
-#
-# import os
-# import sys
-# sys.path.insert(0, os.path.abspath('.'))
-
-
-# -- Project information -----------------------------------------------------
-
-project = 'Mongoid'
-copyright = '2021, MongoDB'
-
-
-# -- General configuration ---------------------------------------------------
-
-# Add any Sphinx extension module names here, as strings. They can be
-# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
-# ones.
-extensions = [
-]
-
-# Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
-
-# List of patterns, relative to source directory, that match files and
-# directories to ignore when looking for source files.
-# This pattern also affects html_static_path and html_extra_path.
-exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
-
-
-# -- Options for HTML output -------------------------------------------------
-
-# The theme to use for HTML and HTML Help pages. See the documentation for
-# a list of builtin themes.
-#
-html_theme = 'alabaster'
-
-# Add any paths that contain custom static files (such as style sheets) here,
-# relative to this directory. They are copied after the builtin static files,
-# so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
-
-source_suffix = {
- '.txt': 'restructuredtext',
-}
-
-html_theme = 'sphinx_book_theme'
diff --git a/docs/contributing.txt b/docs/contributing.txt
deleted file mode 100644
index abb7d73714..0000000000
--- a/docs/contributing.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-.. _contributing:
-
-************
-Contributing
-************
-
-.. default-domain:: mongodb
-
-.. toctree::
- :titlesonly:
-
- contributing/code-documentation
- contributing/contributing-guidelines
-
-Overview
---------
-
-Learn how to contribute to the Mongoid repository in the following sections:
-
-- :ref:`Code Documentation `
-- :ref:`Contributing Guidelines `
\ No newline at end of file
diff --git a/docs/contributing/code-documentation.txt b/docs/contributing/code-documentation.txt
deleted file mode 100644
index 9713ce278a..0000000000
--- a/docs/contributing/code-documentation.txt
+++ /dev/null
@@ -1,353 +0,0 @@
-.. _code-documentation:
-
-******************
-Code Documentation
-******************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Code Documentation
-==================
-
-Mongoid uses its own flavor of `YARD `_
-for code documentation. Please note the conventions outlined in this document.
-
-
-.. _code-documentation-structure:
-
-Structure
----------
-
-- **Modules:** All class and module definitions should be preceded by
- a documentation comment.
-
- .. code-block:: ruby
-
- # This is the documentation for the class. It's amazing
- # what they do with corrugated cardboard these days.
- class CardboardBox
-
-- **Methods:** All method definitions should be preceded by a documentation comment.
- Use ``@param``, ``@yield``, and ``@return`` to specify inputs and output.
- For further details, refer to
- :ref:`Type Declaration ` below.
-
- .. code-block:: ruby
-
- # Turn a person into whatever they'd like to be.
- #
- # @param [ Person ] person The human to transmogrify.
- #
- # @return [ Tiger ] The transmogrified result.
- def transmogrify(person)
-
-- **Errors:** Use ``@raise`` to explain errors specific to the method.
-
- .. code-block:: ruby
-
- # @raise [ Errors::Validations ] If validation failed.
- def validate!
-
-- **Private Methods:** Private methods should be documented unless they are
- so brief and straightforward that it is obvious what they do. Note that,
- for example, a method may be brief and straightforward but the type of
- its parameter may not be obvious, in which case the parameter must be
- appropriately documented.
-
- .. code-block:: ruby
-
- private
-
- # Documentation is optional here.
- def do_something_obvious
-
-- **API Private:** Classes and public methods which are not intended for
- external usage should be marked ``@api private``. This macro does not
- require a comment.
-
- Note that, because Mongoid's modules are mixed into application classes,
- ``private`` visibility of a method does not necessarily indicate its
- status as an API private method.
-
- .. code-block:: ruby
-
- # This is an internal-only method.
- #
- # @api private
- def dont_call_me_from_outside
-
-- **Notes and TODOs:** Use ``@note`` to explain caveats, edge cases,
- and behavior which may surprise users. Use ``@todo`` to record
- follow-ups and suggestions for future improvement.
-
- .. code-block:: ruby
-
- # Clear all stored data.
- #
- # @note This operation deletes data in the database.
- # @todo Refactor this method for performance.
- def erase_data!
-
-- **Deprecation:** Use the ``@deprecated`` macro to indicate deprecated
- functionality. This macro does not require a comment.
-
- .. code-block:: ruby
-
- # This is how we did things back in the day.
- #
- # @deprecated
- def the_old_way
-
-
-.. _code-documentation-formatting:
-
-Formatting
-----------
-
-- **Line Wrapping:** Use double-space indent when wrapping lines of macros.
- Do not indent line wraps in the description.
-
- .. code-block:: ruby
-
- # This is the description of the method. Line wraps in the description
- # should not be indented.
- #
- # @return [ Symbol ] For macros, wraps must be double-space indented
- # on the second, third, etc. lines.
-
-- **Whitespace:** Do not use leading/trailing empty comment lines,
- or more than one consecutive empty comment line.
-
- .. code-block:: ruby
-
- # GOOD:
- # @return [ Symbol ] The return value
- def my_method
-
- # BAD:
- # @return [ Symbol ] The return value
- #
- def my_method
-
- # BAD:
- # @param [ Symbol ] foo The input value
- #
- #
- # @return [ Symbol ] The return value
- def my_method(foo)
-
-
-.. _code-documentation-type-declaration:
-
-Type Declaration
-----------------
-
-- **Type Unions:** Use pipe ``|`` to denote a union of allowed types.
-
- .. code-block:: ruby
-
- # @param [ Symbol | String ] name Either a Symbol or a String.
-
-- **Nested Types:** Use angle brackets ``< >`` to denote type nesting.
-
- .. code-block:: ruby
-
- # @param [ Array ] array An Array of symbols.
-
-- **Hash:** Use comma ``,`` to denote the key and value types.
-
- .. code-block:: ruby
-
- # @param [ Hash ] hash A Hash whose keys are Symbols,
- # and whose values are Integers.
-
-- **Array:** Use pipe ``|`` to denote a union of allowed types.
-
- .. code-block:: ruby
-
- # @param [ Array ] array An Array whose members must
- # be either Symbols or Strings.
-
-- **Array:** Use comma ``,`` to denote the types of each position in a tuple.
-
- .. code-block:: ruby
-
- # @return [ Array ] A 3-member Array whose first
- # element is a Symbol, and whose second and third elements are Integers.
-
-- **Array:** Use pipe ``|`` on the top level if the inner types cannot be
- mixed within the Array.
-
- .. code-block:: ruby
-
- # @param [ Array | Array ] array An Array containing only
- # Symbols, or an Array containing only Hashes. The Array may not contain
- # a mix of Symbols and Hashes.
-
-- **Nested Types:** For clarity, use square brackets ``[ ]`` to denote nested unions
- when commas are also used.
-
- .. code-block:: ruby
-
- # @param [ Hash ] hash A Hash whose keys are Symbols,
- # and whose values are boolean values.
-
-- **Ruby Values:** Specific values may be denoted in the type using Ruby syntax.
-
- .. code-block:: ruby
-
- # @param [ :before | :after ] timing One of the Symbol values :before or :after.
-
-- **True, False, and Nil:** Use ``true``, ``false``, and ``nil`` rather than
- ``TrueClass``, ``FalseClass``, and ``NilClass``. Do not use ``Boolean`` as a type
- since it does not exist in Ruby.
-
- .. code-block:: ruby
-
- # GOOD:
- # @param [ true | false | nil ] bool A boolean or nil value.
-
- # BAD:
- # @param [ TrueClass | FalseClass | NilClass ] bool A boolean or nil value.
- # @param [ Boolean ] bool A boolean value.
-
-- **Return Self:** Specify return value ``self`` where a method returns ``self``.
-
- .. code-block:: ruby
-
- # @return [ self ] Returns the object itself.
-
-- **Splat Args:** Use three-dot ellipses ``...`` in the type declaration and
- star ``*`` in the parameter name to denote a splat.
-
- .. code-block:: ruby
-
- # @param [ String... ] *items The list of items name(s) as Strings.
- def buy_groceries(*items)
-
-- **Splat Args:** Do not use ``Array`` as the type unless each arg is actually an Array.
-
- .. code-block:: ruby
-
- # BAD:
- # @param [ Array ] *items The list of items name(s) as Strings.
- def buy_groceries(*items)
-
- buy_groceries("Cheese", "Crackers", "Wine")
-
- # OK:
- # @param [ Array... ] *arrays One or more arrays containing name parts.
- def set_people_names(*arrays)
-
- set_people_names(["Harlan", "Sanders"], ["Jane", "K", ""Doe"], ["Jim", "Beam"])
-
-- **Splat Args:** Use comma ``,`` to denote positionality in a splat.
-
- .. code-block:: ruby
-
- # @param [ Symbol..., Hash ] *args A list of names, followed by a hash
- # as the optional last arg.
- def say_hello(*args)
-
-- **Splat Args:** Specify type unions with square brackets ``[ ]``.
-
- .. code-block:: ruby
-
- # @param [ [ String | Symbol ]... ] *fields A splat of mixed Symbols and Strings.
-
-- **Keyword Arguments:** Following YARD conventions, use ``@param`` for keyword
- arguments, and specify keyword argument names as symbols.
-
- .. code-block:: ruby
-
- # @param [ String ] query The search string
- # @param [ Boolean ] :exact_match Whether to do an exact match
- # @param [ Integer ] :results_per_page Number of results
- def search(query, exact_match: false, results_per_page: 10)
-
-- **Hash Options:** Define hash key-value options with ``@option`` macro
- immediately following the Hash ``@param``. Note ``@option`` parameter names
- are symbols.
-
- .. code-block:: ruby
-
- # @param opts [ Hash ] The optional hash argument(s).
- # @option opts [ String | Array ] :items The items(s) as Strings to include.
- # @option opts [ Integer ] :limit An Integer denoting the limit.
- def buy_groceries(opts = {})
-
-- **Double Splats:** Use double-star ``**`` in the parameter name to denote a
- keyword arg splat (double splat). Note that type does not need declared on
- the double-splat element, as it is implicitly . Instead,
- define value types with ``@option`` macro below. Note ``@option`` parameter
- names are symbols.
-
- .. code-block:: ruby
-
- # @param **kwargs The optional keyword argument(s).
- # @option **kwargs [ String | Array ] :items The items(s) as Strings to include.
- # @option **kwargs [ Integer ] :limit An Integer denoting the limit.
- def buy_groceries(**kwargs)
-
-- **Blocks:** Use ``@yield`` to specify when the method yields to a block.
-
- .. code-block:: ruby
-
- # @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime.
- # Must take the person, location, and weapon used. Must return true or false.
- def whodunit
- yield(:mustard, :ballroom, :candlestick)
- end
-
-- **Blocks:** If the method explicitly specifies a block argument, specify the block
- argument using ``@param`` preceded by an ampersand ``&``, and also specify ``@yield``.
- Note ``@yield`` should be used even when method calls ``block.call`` rather than
- ``yield`` internally.
-
- .. code-block:: ruby
-
- # @param &block The block.
- # @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime.
- # Must take the person, location, and weapon used. Must return true or false.
- def whodunit(&block)
- yield(:scarlet, :library, :rope)
- end
-
- # @param &block The block.
- # @yield [ Symbol, Symbol, Symbol ] Evaluate the guess of who did the crime.
- # Must take the person, location, and weapon used. Must return true or false.
- def whodunit(&block)
- block.call(:plum, :kitchen, :pipe)
- end
-
-- **Blocks:** Use ``@yieldparam`` and ``@yieldreturn`` instead of ``@yield`` where
- beneficial for clarity.
-
- .. code-block:: ruby
-
- # @param &block The block.
- # @yieldparam [ Symbol ] The person.
- # @yieldparam [ Symbol ] The location.
- # @yieldparam [ Symbol ] The weapon used.
- # @yieldreturn [ true | false ] Whether the guess is correct.
- def whodunit(&block)
- yield(:peacock, :conservatory, :wrench)
- end
-
-- **Proc Args:** Proc arguments should use ``@param`` (not ``@yield``). The
- inputs to the proc may be specified as subtype(s).
-
- .. code-block:: ruby
-
- # @param [ Proc ] my_proc Proc argument which must
- # take 3 integers and must return true or false whether the guess is valid.
- def guess_three(my_proc)
- my_proc.call(42, 7, 88)
- end
diff --git a/docs/contributing/contributing-guidelines.txt b/docs/contributing/contributing-guidelines.txt
deleted file mode 100644
index 68491bd5b2..0000000000
--- a/docs/contributing/contributing-guidelines.txt
+++ /dev/null
@@ -1,43 +0,0 @@
-.. _contributing-guidelines:
-
-***********************
-Contributing Guidelines
-***********************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Contributing Guidelines
-=======================
-
-If you wish to propose an enhancement to Mongoid, please create a Jira ticket
-describing the enhancement and what it would enable you to achieve in your
-application that is not already possible. If you believe Mongoid is not
-behaving correctly, please create a Jira ticket describing how you use Mongoid,
-what the existing behavior is that you consider incorrect or problematic, and
-what your desired behavior is. If you wish to make changes yourself, the
-following guildelines should be followed:
-
-#. Create a fork of Mongoid.
-#. Create a new branch in that fork.
-#. Make your changes.
-#. Ensure that the proposed changes have adequate test coverage.
-#. Raise a PR against Mongoid master. If these changes correspond to a specific
- Jira ticket, title the PR: "MONGOID- Description of Changes".
-#. The Mongoid team will review the PR and make comments/suggest changes.
-#. Once all of the changes and fixes are made, and the Mongoid team determine
- the PR fit for merging, we will merge the PR into master and determine
- whether it needs to be backported.
-#. Backports to previous stable versions are done if the change is a bug fix,
- is not backwards breaking, and if the commit is applicable to the
- corresponding stable branch. Presently backport candidates would include
- versions 7.3-8.0.
-#. Changes to 6.0-7.2 are generally not made unless it fixes a security
- vulnerability.
-#. 5.x and earlier is generally not supported.
\ No newline at end of file
diff --git a/docs/ecosystem.txt b/docs/ecosystem.txt
deleted file mode 100644
index a754c45ec4..0000000000
--- a/docs/ecosystem.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-*********
-Ecosystem
-*********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Mongoid has an extensive ecosystem of libraries integrating with or built
-on top of Mongoid, are listed below.
-
-
-Projects
-========
-
-- `Workarea Commerce `_
-
- Workarea is an enterprise-grade Ruby on Rails commerce platform that uses Mongoid.
-
-
-Extension Libraries
-===================
-
-- `Mongoid Tree `_
-
- A tree structure for Mongoid documents using the materialized path pattern.
-
-- `Mongoid Token `_
-
- A little random, unique token generator for Mongoid documents.
-
-- `Mongoid Collection Snapshot `_
-
- Easy maintenance of collections of processed data in MongoDB with the Mongoid ODM.
-
-- `Mongoid Locker `_
-
- Document-level locking for MongoDB via Mongoid.
-
-- `Mongo Beautiful Logger `_
-
- A simple and beautiful logger library for MongoDB in your Ruby/Rails app.
-
-- `Mongoid Search `_
-
- Simple full text search for Mongoid.
-
-- `Mongoid Fulltext Search `_
-
- Full-text search using n-gram matching for the Mongoid ODM.
-
-
-Integration Libraries
-=====================
-
-- `CarrierWave Mongoid `_
-
- Mongoid Support for the Carrierwave file uploads library.
-
-- `Mongoid RSpec `_
-
- RSpec matchers and macros for Mongoid applications.
-
-- `RailsAdmin `_ supports Mongoid out
- of the box.
-
-- `ActiveAdmin Mongoid `_
-
- ActiveAdmin hacks to support Mongoid.
-
-- `Mongoid History `_
-
- Multi-user non-linear history tracking, auditing, undo, redo for mongoid.
-- `Delayed Job Mongoid `_
-
- Mongoid backend for delayed_job.
-
-- `Mongo Session Store `_
-
- A Rails-compatible session store for Mongoid.
diff --git a/docs/img/rails-blog-new-comment.png b/docs/img/rails-blog-new-comment.png
deleted file mode 100644
index f82a56e9f6..0000000000
Binary files a/docs/img/rails-blog-new-comment.png and /dev/null differ
diff --git a/docs/img/rails-new-blog.png b/docs/img/rails-new-blog.png
deleted file mode 100644
index 210355a261..0000000000
Binary files a/docs/img/rails-new-blog.png and /dev/null differ
diff --git a/docs/includes/unicode-ballot-x.rst b/docs/includes/unicode-ballot-x.rst
deleted file mode 100644
index 50c3667ae6..0000000000
--- a/docs/includes/unicode-ballot-x.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. |x| unicode:: U+2717
diff --git a/docs/includes/unicode-checkmark.rst b/docs/includes/unicode-checkmark.rst
deleted file mode 100644
index 16f4e94764..0000000000
--- a/docs/includes/unicode-checkmark.rst
+++ /dev/null
@@ -1 +0,0 @@
-.. |checkmark| unicode:: U+2713
diff --git a/docs/index.txt b/docs/index.txt
deleted file mode 100644
index 0f320dd552..0000000000
--- a/docs/index.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-.. _mongoid:
-
-*******
-Mongoid
-*******
-
-.. default-domain:: mongodb
-
-Mongoid is the officially supported object-document mapper (ODM) for MongoDB in
-Ruby. To work with Mongoid from the command line using ``rails``-like tooling,
-the `railsmdb `_ utility can be used.
-
-.. toctree::
- :titlesonly:
-
- installation-configuration
- tutorials
- schema-configuration
- working-with-data
- API
- release-notes
- contributing
- additional-resources
- ecosystem
diff --git a/docs/installation-configuration.txt b/docs/installation-configuration.txt
deleted file mode 100644
index fd5ea05b3a..0000000000
--- a/docs/installation-configuration.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-.. _installation-configuration:
-
-****************************
-Installation & Configuration
-****************************
-
-.. default-domain:: mongodb
-
-.. toctree::
- :titlesonly:
-
- installation
- reference/compatibility
- reference/configuration
- reference/rails-integration
-
-Overview
---------
-
-Learn how to install and configure Mongoid in the following sections:
-
-- :ref:`Installation `
-- :ref:`Compatibility `
-- :ref:`Configuration `
-- :ref:`Rails Integration `
\ No newline at end of file
diff --git a/docs/installation.txt b/docs/installation.txt
deleted file mode 100644
index bd9e290890..0000000000
--- a/docs/installation.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-.. _installation:
-
-************
-Installation
-************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Install the Gem
-===============
-
-Mongoid is bundled as a gem, and is `hosted on Rubygems
-`_.
-It can be installed manually or with bundler.
-
-To install the gem manually:
-
-.. code-block:: sh
-
- gem install mongoid
-
-To install the gem with bundler, include the following in your ``Gemfile``:
-
-.. code-block:: ruby
-
- gem 'mongoid'
-
-Using Mongoid with a New Rails Application
-==========================================
-
-By using the `railsmdb CLI `_ a new
-Ruby on Rails application can be quickly generated using the same options as
-``rails new``, but configured to work with MongoDB:
-
-.. code-block:: sh
-
- railsmdb new my_new_rails_app
-
-The ``rails`` CLI can also be used, however when creating a new Rails application
-and where Mongoid will be used for data access, provide the ``--skip-active-record``
-flag to the ``rails new`` command to avoid depending on and configuring ActiveRecord.
-
-Additional examples can be found in the `tutorials `_.
-
-Using Mongoid with an Existing Rails Application
-================================================
-
-Using the `railsmdb CLI `_ an existing
-Rails application can easily be configured for use with Mongoid:
-
-.. code-block:: sh
-
- railsmdb setup
-
-Converting an existing Rails application without using ``railsmdb`` can be done
-by updating the ``config/application.rb`` file to remove the ``require 'rails/all'``
-line and explicitly include the required frameworks (which could be all of the
-frameworks provided by Rails with the exception ofActiveRecord).
-Any references to ActiveRecord in files in the ``config`` directory and in the
-models also need to be removed.
diff --git a/docs/meta/404.txt b/docs/meta/404.txt
deleted file mode 100644
index 4143ded8d6..0000000000
--- a/docs/meta/404.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-:orphan:
-
-**************
-File not found
-**************
-
-The URL you requested does not exist or has been removed.
diff --git a/docs/nesting-levels.txt b/docs/nesting-levels.txt
deleted file mode 100644
index 2973410d08..0000000000
--- a/docs/nesting-levels.txt
+++ /dev/null
@@ -1,20 +0,0 @@
-This file is not part of Mongoid documentation proper, it is an internal
-reference for the nesting levels that other files should be using.
-
-Mongoid documentation nesting levels:
-
-**********
-Page Title
-**********
-
-First Level Heading
-===================
-
-Second Level Heading
---------------------
-
-Third Level Heading
-```````````````````
-
-Fourth Level Heading
-~~~~~~~~~~~~~~~~~~~~
diff --git a/docs/reference/aggregation.txt b/docs/reference/aggregation.txt
deleted file mode 100644
index 5a5c83d965..0000000000
--- a/docs/reference/aggregation.txt
+++ /dev/null
@@ -1,203 +0,0 @@
-.. _aggregation-pipeline:
-
-********************
-Aggregation Pipeline
-********************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Mongoid exposes `MongoDB's aggregation pipeline
-`_,
-which is used to construct flows of operations that process and return results.
-The aggregation pipeline is a superset of the deprecated
-:ref:`map/reduce framework ` functionality.
-
-
-Basic Usage
-===========
-
-.. _aggregation-pipeline-example-multiple-collections:
-
-Querying Across Multiple Collections
-````````````````````````````````````
-
-The aggregation pipeline may be used for queries involving multiple
-referenced associations at the same time:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- has_many :tours
- has_many :awards
- field :name, type: String
- end
-
- class Tour
- include Mongoid::Document
- belongs_to :band
- field :year, type: Integer
- end
-
- class Award
- include Mongoid::Document
- belongs_to :band
- field :name, type: String
- end
-
-To retrieve bands that toured since 2000 and have at least one award, one
-could do the following:
-
-.. code-block:: ruby
-
- band_ids = Band.collection.aggregate([
- { '$lookup' => {
- from: 'tours',
- localField: '_id',
- foreignField: 'band_id',
- as: 'tours',
- } },
- { '$lookup' => {
- from: 'awards',
- localField: '_id',
- foreignField: 'band_id',
- as: 'awards',
- } },
- { '$match' => {
- 'tours.year' => {'$gte' => 2000},
- 'awards._id' => {'$exists' => true},
- } },
- {'$project' => {_id: 1}},
- ])
- bands = Band.find(band_ids.to_a)
-
-Note that the aggregation pipeline, since it is implemented by the Ruby driver
-for MongoDB and not Mongoid, returns raw ``BSON::Document`` objects rather than
-``Mongoid::Document`` model instances. The above example projects only
-the ``_id`` field which is then used to load full models. An alternative is
-to not perform such a projection and work with raw fields, which would eliminate
-having to send the list of document ids to Mongoid in the second query
-(which could be large).
-
-
-.. _aggregation-pipeline-builder-dsl:
-
-Builder DSL
-===========
-
-Mongoid provides limited support for constructing the aggregation pipeline
-itself using a high-level DSL. The following aggregation pipeline operators
-are supported:
-
-- `$group `_
-- `$project `_
-- `$unwind `_
-
-To construct a pipeline, call the corresponding aggregation pipeline methods
-on a ``Criteria`` instance. Aggregation pipeline operations are added to the
-``pipeline`` attribute of the ``Criteria`` instance. To execute the pipeline,
-pass the ``pipeline`` attribute value to ``Collection#aggragegate`` method.
-
-For example, given the following models:
-
-.. code-block:: ruby
-
- class Tour
- include Mongoid::Document
-
- embeds_many :participants
-
- field :name, type: String
- field :states, type: Array
- end
-
- class Participant
- include Mongoid::Document
-
- embedded_in :tour
-
- field :name, type: String
- end
-
-We can find out which states a participant visited:
-
-.. code-block:: ruby
-
- criteria = Tour.where('participants.name' => 'Serenity',).
- unwind(:states).
- group(_id: 'states', :states.add_to_set => '$states').
- project(_id: 0, states: 1)
-
- pp criteria.pipeline
- # => [{"$match"=>{"participants.name"=>"Serenity"}},
- # {"$unwind"=>"$states"},
- # {"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}},
- # {"$project"=>{"_id"=>0, "states"=>1}}]
-
- Tour.collection.aggregate(criteria.pipeline).to_a
-
-
-group
-`````
-
-The ``group`` method adds a `$group aggregation pipeline stage
-`_.
-
-The field expressions support Mongoid symbol-operator syntax:
-
-.. code-block:: ruby
-
- criteria = Tour.all.group(_id: 'states', :states.add_to_set => '$states')
- criteria.pipeline
- # => [{"$group"=>{"_id"=>"states", "states"=>{"$addToSet"=>"$states"}}}]
-
-Alternatively, standard MongoDB aggregation pipeline syntax may be used:
-
-.. code-block:: ruby
-
- criteria = Tour.all.group(_id: 'states', states: {'$addToSet' => '$states'})
-
-
-project
-```````
-
-The ``project`` method adds a `$project aggregation pipeline stage
-`_.
-
-The argument should be a Hash specifying the projection:
-
-.. code-block:: ruby
-
- criteria = Tour.all.project(_id: 0, states: 1)
- criteria.pipeline
- # => [{"$project"=>{"_id"=>0, "states"=>1}}]
-
-
-.. _unwind-dsl:
-
-unwind
-``````
-
-The ``unwind`` method adds an `$unwind aggregation pipeline stage
-`_.
-
-The argument can be a field name, specifiable as a symbol or a string, or
-a Hash or a ``BSON::Document`` instance:
-
-.. code-block:: ruby
-
- criteria = Tour.all.unwind(:states)
- criteria = Tour.all.unwind('states')
- criteria.pipeline
- # => [{"$unwind"=>"$states"}]
-
- criteria = Tour.all.unwind(path: '$states')
- criteria.pipeline
- # => [{"$unwind"=>{:path=>"$states"}}]
diff --git a/docs/reference/associations.txt b/docs/reference/associations.txt
deleted file mode 100644
index e8f9c7b33e..0000000000
--- a/docs/reference/associations.txt
+++ /dev/null
@@ -1,1655 +0,0 @@
-.. _associations:
-
-************
-Associations
-************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Referenced Associations
-=======================
-
-Mongoid supports the ``has_one``, ``has_many``, ``belongs_to`` and
-``has_and_belongs_to_many`` associations familiar to ActiveRecord users.
-
-
-Has One
--------
-
-Use the ``has_one`` macro to declare that the parent has a child stored in
-a separate collection. The child is optional by default:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_one :studio
- end
-
-When using ``has_one``, the child model must use ``belongs_to`` to declare the
-association with the parent:
-
-.. code-block:: ruby
-
- class Studio
- include Mongoid::Document
-
- belongs_to :band
- end
-
-Given the above definitions, every child document contains a reference to
-its respective parent document:
-
-.. code-block:: ruby
-
- band = Band.create!(studio: Studio.new)
- # => #
-
- band.studio
- # => #
-
-Use validations to require that the child is present:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_one :studio
-
- validates_presence_of :studio
- end
-
-
-Has Many
---------
-
-Use the ``has_many`` association to declare that the parent has zero or more
-children stored in a separate collection:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_many :members
- end
-
-Like with ``has_one``, the child model must use ``belongs_to`` to declare the
-association with the parent:
-
-.. code-block:: ruby
-
- class Member
- include Mongoid::Document
-
- belongs_to :band
- end
-
-Also as with ``has_one``, the child documents contain references to their
-respective parents:
-
-.. code-block:: ruby
-
- band = Band.create!(members: [Member.new])
- # => #
-
- band.members
- # => [#]
-
-Use validations to require that at least one child is present:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_many :members
-
- validates_presence_of :members
- end
-
-
-Queries
-```````
-
-.. _has-many-any:
-
-``any?``
-~~~~~~~~
-
-Use the ``any?`` method on the association to efficiently determine whether
-the association contains any documents, without retrieving the entire set
-of documents from the database:
-
-.. code-block:: ruby
-
- band = Band.first
- band.members.any?
-
-``any?`` also implements the `Enumerable#any? API
-`_, allowing
-filtering with a block:
-
-.. code-block:: ruby
-
- band = Band.first
- band.members.any? { |member| member.instrument == 'piano' }
-
-... or by a class name which can be useful for polymorphic associations:
-
-.. code-block:: ruby
-
- class Drummer < Member
- end
-
- band = Band.first
- band.members.any?(Drummer)
-
-If the association is already loaded, ``any?`` inspects the loaded
-documents and does not query the database:
-
-.. code-block:: ruby
-
- band = Band.first
- # Queries the database
- band.members.any?
-
- band.members.to_a
-
- # Does not query the database
- band.members.any?
-
-Note that simply calling ``any?`` would *not* load the association
-(since ``any?`` only retrieves the _id field of the first matching document).
-
-``exists?``
-~~~~~~~~~~~
-
-The ``exists?`` method on the association determines whether there are
-any *persisted* documents in the association. Unlike the ``any?`` method:
-
-- ``exists?`` always queries the database, even if the association is already
- loaded.
-- ``exists?`` does not consider non-persisted documents.
-- ``exists?`` does not allow filtering in the application like ``any?`` does,
- and does not take any arguments.
-
-The following example illustrates the difference between ``exists?`` and
-``any?``:
-
-.. code-block:: ruby
-
- band = Band.create!
- # Member is not persisted.
- band.members.build
-
- band.members.any?
- # => true
- band.members.exists?
- # => false
-
- # Persist the member.
- band.members.map(&:save!)
-
- band.members.any?
- # => true
- band.members.exists?
- # => true
-
-
-Belongs To
-----------
-
-Use the ``belongs_to`` macro to associate a child with a parent stored in a
-separate collection. The ``_id`` of the parent (if a parent is associated)
-is stored in the child.
-
-By default, if a ``belongs_to`` association is defined on a model, it must be
-provided a value for a model instance to be saved. Use the ``optional: true```
-option to make the instances persistable without specifying the parent:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_one :studio
- end
-
- class Studio
- include Mongoid::Document
-
- belongs_to :band, optional: true
- end
-
- studio = Studio.create!
- # => #
-
-To change the default behavior of ``belongs_to`` associations to not require
-their respective parents globally, set the ``belongs_to_required_by_default``
-:ref:`configuration option ` to ``false``.
-
-Although ``has_one`` and ``has_many`` associations require the
-corresponding ``belongs_to`` association to be defined on the child,
-``belongs_to`` may also be used without a corresponding ``has_one`` or
-``has_many`` macro. In this case the child is not accessible from the parent
-but the parent is accessible from the child:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- end
-
- class Studio
- include Mongoid::Document
-
- belongs_to :band
- end
-
-For clarity it is possible to add the ``inverse_of: nil`` option in cases when
-the parent does not define the association:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- end
-
- class Studio
- include Mongoid::Document
-
- belongs_to :band, inverse_of: nil
- end
-
-
-Has And Belongs To Many
------------------------
-
-Use the ``has_and_belongs_to_many`` macro to declare a many-to-many
-association:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_and_belongs_to_many :tags
- end
-
- class Tag
- include Mongoid::Document
-
- has_and_belongs_to_many :bands
- end
-
-Both model instances store a list of ids of the associated models, if any:
-
-.. code-block:: ruby
-
- band = Band.create!(tags: [Tag.create!])
- # => #
-
- band.tags
- # => [#]
-
-You can create a one-sided ``has_and_belongs_to_many`` association to store
-the ids only in one document using the ``inverse_of: nil`` option:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_and_belongs_to_many :tags, inverse_of: nil
- end
-
- class Tag
- include Mongoid::Document
- end
-
- band = Band.create!(tags: [Tag.create!])
- # => #
-
- band.tags
- # => [#]
-
-A one-sided ``has_and_belongs_to_many`` association is, naturally, only
-usable from the model where it is defined.
-
-.. note::
-
- Given two models, A and B where A ``has_and_belongs_to_many`` B,
- when adding a document of type B to the HABTM association on a document of
- type A, Mongoid will not update the ``updated_at`` field for the document of
- type A, but will update the ``updated_at`` field for the document of type B.
-
-Querying Referenced Associations
---------------------------------
-
-In most cases, efficient queries across referenced associations (and in general
-involving data or conditions or multiple collections) are performed using
-the aggregation pipeline. Mongoid helpers for constructing aggregation pipeline
-queries are described in the :ref:`aggregation pipeline `
-section.
-
-For simple queries, the use of aggregation pipeline may be avoided and
-associations may be queried directly. When querying associations directly,
-all conditions must be on that association's collection only (which typically
-means association in question and any associations embedded in it).
-
-For example, given the following models:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_many :tours
- has_many :awards
-
- field :name, type: String
- end
-
- class Tour
- include Mongoid::Document
-
- belongs_to :band
-
- field :year, type: Integer
- end
-
- class Award
- include Mongoid::Document
-
- belongs_to :band
-
- field :name, type: String
- end
-
-One could retrieve all bands that have toured since 2000 as follows:
-
-.. code-block:: ruby
-
- band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
- bands = Band.find(band_ids)
-
-The conditions on ``Tour`` can be arbitrarily complex, but they must all
-be on the same ``Tour`` document (or documents embedded in ``Tour``).
-
-To find awards for bands that have toured since 2000:
-
-.. code-block:: ruby
-
- band_ids = Tour.where(year: {'$gte' => 2000}).pluck(:band_id)
- awards = Award.where(band_id: {'$in' => band_ids})
-
-
-Embedded Associations
-=====================
-
-Thanks to MongoDB's document model, Mongoid also offers embedded associations
-which allow documents of different types to be stored hierarchically
-in the same collection. Embedded associations are defined using
-``embeds_one``, ``embeds_many`` and ``embedded_in`` macros, plus
-``recursively_embeds_one`` and ``recursively_embeds_many`` for recursive
-embedding.
-
-Embeds One
-----------
-
-One to one associations where the children are embedded in the parent
-document are defined using Mongoid's ``embeds_one`` and ``embedded_in`` macros.
-
-Defining
-````````
-
-The parent document of the association should use the ``embeds_one`` macro to
-indicate is has one embedded child, where the document that is embedded uses
-``embedded_in``. Definitions are required on both sides to the association
-in order for it to work properly.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_one :label
- end
-
- class Label
- include Mongoid::Document
- field :name, type: String
- embedded_in :band
- end
-
-Storage
-```````
-
-Documents that are embedded using the ``embeds_one`` macro are stored as a
-hash inside the parent in the parent's database collection.
-
-.. code-block:: ruby
-
- {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
- "label" : {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
- "name" : "Mute",
- }
- }
-
-You can optionally tell Mongoid to store the embedded document in a different
-attribute other than the name, by providing the ``:store_as`` option.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_one :label, store_as: "lab"
- end
-
-
-Embeds Many
------------
-
-One to many relationships where the children are embedded in the parent
-document are defined using Mongoid's ``embeds_many`` and ``embedded_in`` macros.
-
-Defining
-````````
-
-The parent document of the association should use the ``embeds_many`` macro
-to indicate it has many embedded children, where the document that is
-embedded uses ``embedded_in``. Definitions are required on both sides of
-the association in order for it to work properly.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :albums
- end
-
- class Album
- include Mongoid::Document
- field :name, type: String
- embedded_in :band
- end
-
-Storage
-```````
-
-Documents that are embedded using the ``embeds_many`` macro are stored as
-an array of hashes inside the parent in the parent's database collection.
-
-.. code-block:: ruby
-
- {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
- "albums" : [
- {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
- "name" : "Violator",
- }
- ]
- }
-
-You can optionally tell Mongoid to store the embedded document in a different
-attribute other than the name, by providing the ``:store_as`` option.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :albums, store_as: "albs"
- end
-
-Recursive Embedding
--------------------
-
-A document can recursively embed itself using ``recursively_embeds_one`` or
-``recursively_embeds_many``, which provides accessors for the parent and
-children via ``parent_`` and ``child_`` methods.
-
-.. code-block:: ruby
-
- class Tag
- include Mongoid::Document
- field :name, type: String
- recursively_embeds_many
- end
-
- root = Tag.new(name: "programming")
- child_one = root.child_tags.build
- child_two = root.child_tags.build
-
- root.child_tags # [ child_one, child_two ]
- child_one.parent_tag # [ root ]
- child_two.parent_tag # [ root ]
-
- class Node
- include Mongoid::Document
- recursively_embeds_one
- end
-
- root = Node.new
- child = Node.new
- root.child_node = child
-
- root.child_node # child
- child.parent_node # root
-
-Referencing Vs Embedding
-------------------------
-
-While a complete discussion of referencing vs embedding is beyond the scope
-of this tutorial, here are some high level considerations for choosing
-one over the other.
-
-When an association is embedded, both parent and child documents are stored
-in the same collection. This permits efficient persistence and retrieval
-when both are used/needed. For example, if the navigation bar on a web site
-shows attributes of a user that are stored in documents themselves, it is
-often a good idea to use embedded associations.
-
-Using embedded associations allows using MongoDB tools like the
-`aggregation pipeline
-`_ to query
-these documents in a powerful way.
-
-Because embedded documents are stored as part of their parent top-level
-documents, it is not possible to persist an embedded document by itself,
-nor is it possible to retrieve embedded documents directly. However,
-embedded documents can still be efficiently queried and retrieved with the
-help of MongoDB projection operation:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :started_on, type: Date
- embeds_one :label
- end
-
- class Label
- include Mongoid::Document
- field :name, type: String
- embedded_in :band
- end
-
- # Retrieve labels for bands started in the last year.
- #
- # Sends a find query like this:
- # {"find"=>"bands",
- # "filter"=>{"started_on"=>{"$gt"=>2018-07-01 00:00:00 UTC}},
- # "projection"=>{"_id"=>1, "label"=>1}}
- Band.where(started_on: {'$gt' => Time.now - 1.year}).only(:label).map(&:label).compact.uniq
-
-Setting Stale Values on Referenced Associations
-```````````````````````````````````````````````
-
-Setting a stale value to a referenced association can sometimes result in
-a ``nil`` value being persisted to the database. Take the following case:
-
-.. code-block:: ruby
-
- class Post
- include Mongoid::Document
-
- has_one :comment, inverse_of: :post
- end
-
- class Comment
- include Mongoid::Document
-
- belongs_to :post, inverse_of: :comment, optional: true
- end
-
- post.comment = comment1
- post.reload
-
-At this point, ``post.comment`` is set to ``comment1``, however since a reload
-happened, ``post.comment`` does not refer to the same object as ``comment1``.
-Meaning, updating one object does not implicitly update the other. This matters
-for the next operation:
-
-.. code-block:: ruby
-
- post.comment = comment2
- post.reload
-
-Now, ``post.comment`` is set to ``comment2``, and the ``post_id`` of the old
-comment is set to ``nil``. However, the value that was assigned to
-``post.comment`` did not refer to the same object as ``comment1``, therefore,
-while the old value of ``post.comment`` was updated to have a ``nil``
-``post_id``, ``comment1`` still has the ``post_id`` set.
-
-.. code-block:: ruby
-
- post.comment = comment1
- post.reload
-
-Finally, this last assignment attempts to set the ``post_id`` on ``comment1``,
-which should be ``nil`` at this point, but is set to the old ``post_id``.
-During this operation, the ``post_id`` is cleared from ``comment2``, and the
-new ``post_id`` is set on ``comment1``. However, since the ``post_id`` was
-already set on ``comment1``, nothing is persisted, and we end up with both
-comments having a ``nil`` ``post_id``. At this point, running ``post.comment``
-returns ``nil``.
-
-
-Querying Embedded Associations
-------------------------------
-
-When querying top-level documents, conditions can be specified on documents
-in embedded associations using the dot notation. For example, given the
-following models:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :tours
- embeds_many :awards
- field :name, type: String
- end
-
- class Tour
- include Mongoid::Document
- embedded_in :band
- field :year, type: Integer
- end
-
- class Award
- include Mongoid::Document
- embedded_in :band
- field :name, type: String
- end
-
-To retrieve bands based on tour attributes, use the dot notation as follows:
-
-.. code-block:: ruby
-
- # Get all bands that have toured since 2000
- Band.where('tours.year' => {'$gte' => 2000})
-
-To retrieve only documents of embedded associations, without retrieving
-top-level documents, use the ``pluck`` projection method:
-
-.. code-block:: ruby
-
- # Get awards for bands that have toured since 2000
- Band.where('tours.year' => {'$gte' => 2000}).pluck(:awards)
-
-.. _embedded-matching:
-
-Querying Loaded Associations
-````````````````````````````
-
-Mongoid query methods can be used on embedded associations of documents which
-are already loaded in the application. This mechanism is called
-"embedded matching" and it is implemented entirely in Mongoid--the queries
-are NOT sent to the server.
-
-The following operators are supported:
-
-- :manual:`Comparison operators `
-- :manual:`Logical operators `
-- :manual:`Array query operators `
-- :manual:`$exists `
-- :manual:`$mod `
-- :manual:`$type `
-- :manual:`$regex ` (``$options`` field
- is only supported when the ``$regex`` argument is a string)
-- :manual:`Bitwise operators `
-- :manual:`$comment `
-
-For example, using the model definitions just given, we could query
-tours on a loaded band:
-
-.. code-block:: ruby
-
- band = Band.where(name: 'Astral Projection').first
- tours = band.tours.where(year: {'$gte' => 2000})
-
-Embedded Matching vs Server Behavior
-````````````````````````````````````
-
-Mongoid's embedded matching aims to support the same functionality and
-semantics as native queries on the latest MongoDB server version.
-Note the following known limitations:
-
-- Embedded matching is not implemented for :ref:`text search `,
- :manual:`geospatial query operators `,
- operators that execute JavaScript code (:manual:`$where `)
- and operators that are implemented via other server functionality such as
- :manual:`$expr `
- and :manual:`$jsonSchema `.
-
-- Mongoid DSL expands ``Range`` arguments to hashes with ``$gte`` and ``$lte``
- conditions. `In some cases `_
- this creates bogus queries. Embedded matchers raise the ``InvalidQuery``
- exception in these cases. The operators that are known to be affected are
- ``$elemMatch``, ``$eq``, ``$gt``, ``$gte``, ``$lt``, ``$lte`` and ``$ne``.
-
-- When performing embedded matching with ``$regex``, `it is not currently
- possible `_ to specify a
- regular expression object as the pattern and also provide options.
-
-- MongoDB Server 4.0 and earlier servers do not validate ``$type`` arguments strictly
- (for example, allowing invalid arguments like 0). This is validated more strictly on
- the client side.
-
-
-.. _omit-id:
-
-Omitting ``_id`` Fields
------------------------
-
-By default, Mongoid adds an ``_id`` field to each embedded document. This
-permits easy referencing of and operations on the embedded documents.
-
-These ``_id`` fields may be omitted to save storage space. To do so,
-:ref:`override the _id field definition in the child documents `
-and remove the default value:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
-
- embeds_many :line_items
- end
-
- class LineItem
- include Mongoid::Document
-
- embedded_in :order
-
- field :_id, type: Object
- end
-
-In the current version of Mongoid the field definition is required, but
-without a default value specified no value will be stored in the database.
-A future version of Mongoid may allow removing previously defined fields.
-
-.. note::
-
- Removing the ``_id`` field means that embedded documents must be identified
- by their content attribute values during queries, updates and deletes.
-
-
-Deleting
---------
-
-Mongoid provides three methods for deleting children from ``embeds_many``
-associations: ``clear``, ``destroy_all`` and ``delete_all``.
-
-``clear``
-`````````
-
-The ``clear`` method uses the :manual:`$unset operator
-` to remove the entire association from the
-host document. It does not run destroy callbacks on the documents being removed,
-acting like ``delete_all`` in this regard:
-
-.. code-block:: ruby
-
- band = Band.find(...)
- band.tours.clear
-
-If ``clear`` is called on an association in an unsaved host document, it will
-still try to remove the association from the database based on the host
-document's ``_id``:
-
-.. code-block:: ruby
-
- band = Band.find(...)
- band.tours << Tour.new(...)
-
- unsaved_band = Band.new(id: band.id, tours: [Tour.new])
- # Removes all tours from the persisted band due to _id match.
- unsaved_band.tours.clear
-
- band.tours
- # => []
-
-``delete_all``
-``````````````
-
-The ``delete_all`` method removes the documents that are in the association
-using the :manual:`$pullAll operator `.
-Unlike ``clear``, ``delete_all``:
-
-- Loads the association, if it wasn't yet loaded;
-- Only removes the documents that exist in the application.
-
-``delete_all`` does not run destroy callbacks on the documents being removed.
-
-Example:
-
-.. code-block:: ruby
-
- band = Band.find(...)
- band.tours.delete_all
-
-
-``destroy_all``
-```````````````
-
-The ``delete_all`` method removes the documents that are in the association
-using the :manual:`$pullAll operator `
-while running the destroy callbacks. Like ``delete_all``, ``destroy_all``
-loads the entire association if it wasn't yet loaded and it only removes
-documents that exist in the application:
-
-.. code-block:: ruby
-
- band = Band.find(...)
- band.tours.destroy_all
-
-
-.. _hash-assignment:
-
-Hash Assignment
----------------
-
-Embedded associations allow the user to assign a ``Hash`` instead of a document
-to an association. On assignment, this hash is coerced into a document of the
-class of the association that it's being assigned to. Take the following
-example:
-
-.. code:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :albums
- end
-
- class Album
- include Mongoid::Document
- field :name, type: String
- embedded_in :band
- end
-
- band = Band.create!
- band.albums = [ { name: "Narrow Stairs" }, { name: "Transatlanticism" } ]
- p band.albums
- # => [ #, # ]
-
-This works for ``embeds_one``, ``embeds_many``, and ``embedded_in`` associations.
-Note that you cannot assign hashes to referenced associations.
-
-
-Common Behavior
-===============
-
-Extensions
-----------
-
-All associations can have extensions, which provides a way to add application specific
-functionality to the association. They are defined by providing a block to the association definition.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- embeds_many :addresses do
- def find_by_country(country)
- where(country: country).first
- end
- def chinese
- _target.select { |address| address.country == "China" }
- end
- end
- end
-
- person.addresses.find_by_country("Mongolia") # returns address
- person.addresses.chinese # returns [ address ]
-
-Custom Association Names
-------------------------
-
-You can name your associations whatever you like, but if the class cannot be inferred by
-Mongoid from the name, and neither can the opposite side you'll want to provide the
-macro with some additional options to tell Mongoid how to hook them up.
-
-.. code-block:: ruby
-
- class Car
- include Mongoid::Document
- embeds_one :engine, class_name: "Motor", inverse_of: :machine
- end
-
- class Motor
- include Mongoid::Document
- embedded_in :machine, class_name: "Car", inverse_of: :engine
- end
-
-Custom Primary & Foreign Keys
------------------------------
-
-The fields used when looking up associations can be explicitly specified.
-The default is to use ``id`` on the "parent" association and ``#{association_name}_id``
-on the "child" association, for example with a has_many/belongs_to:
-
-.. code-block:: ruby
-
- class Company
- include Mongoid::Document
- has_many :emails
- end
-
- class Email
- include Mongoid::Document
- belongs_to :company
- end
-
- company = Company.find(id)
- # looks up emails where emails.company_id == company.id
- company.emails
-
-Specify a different ``primary_key`` to change the field name on the "parent"
-association and ``foreign_key`` to change the field name on the "child"
-association:
-
-.. code-block:: ruby
-
- class Company
- include Mongoid::Document
- field :c, type: String
- has_many :emails, foreign_key: 'c_ref', primary_key: 'c'
- end
-
- class Email
- include Mongoid::Document
- # This definition of c_ref is automatically generated by Mongoid:
- # field :c_ref, type: Object
- # But the type can also be specified:
- field :c_ref, type: String
- belongs_to :company, foreign_key: 'c_ref', primary_key: 'c'
- end
-
- company = Company.find(id)
- # looks up emails where emails.c_ref == company.c
- company.emails
-
-With a has_and_belongs_to_many association, since the data is stored on both
-sides of the association, there are 4 fields configurable when the association
-is defined:
-
-- ``:primary_key`` is the field on the remote model that contains the value
- by which the remote model is looked up.
-- ``:foreign_key`` is the field on the local model which stores the
- ``:primary_key`` values.
-- ``:inverse_primary_key`` is the field on the local model that the remote
- model uses to look up the local model documents.
-- ``:inverse_foreign_key`` is the field on the remote model storing the
- values in ``:inverse_primary_key``.
-
-An example might make this more clear:
-
-.. code-block:: ruby
-
- class Company
- include Mongoid::Document
-
- field :c_id, type: Integer
- field :e_ids, type: Array
-
- has_and_belongs_to_many :employees,
- primary_key: :e_id, foreign_key: :e_ids,
- inverse_primary_key: :c_id, inverse_foreign_key: :c_ids
- end
-
- class Employee
- include Mongoid::Document
-
- field :e_id, type: Integer
- field :c_ids, type: Array
-
- has_and_belongs_to_many :companies,
- primary_key: :c_id, foreign_key: :c_ids,
- inverse_primary_key: :e_id, inverse_foreign_key: :e_ids
- end
-
- company = Company.create!(c_id: 123)
- # => #
-
- employee = Employee.create!(e_id: 456)
- # => #
-
- company.employees << employee
-
- company
- # => #
-
- employee
- # => #
-
-Note that just like with the default ``#{association_name}_id`` field,
-Mongoid automatically adds a field for the custom foreign key ``c_ref`` to
-the model. However, since Mongoid doesn't know what type of data should be
-allowed in the field, the field is created with a type of Object. It is a
-good idea to explicitly define the field with the appropriate type.
-
-
-.. _association-scope:
-
-Custom Scopes
--------------
-
-You may set a specific scope on an association using the ``:scope`` parameter.
-The scope is an additional filter that restricts which objects are considered
-to be a part of the association - a scoped association will return only
-documents which satisfy the scope condition.. The scope may be either:
-
-- a ``Proc`` with arity zero, or
-- a ``Symbol`` which references a :ref:`named scope ` on the
- associated model.
-
-.. code-block:: ruby
-
- class Trainer
- has_many :pets, scope: -> { where(species: 'dog') }
- has_many :toys, scope: :rubber
- end
-
- class Pet
- belongs_to :trainer
- end
-
- class Toy
- scope :rubber, where(material: 'rubber')
- belongs_to :trainer
- end
-
-.. note::
-
- It is possible to add documents that do not satisfy an association's scope
- to that association. In this case, such documents will appear associated
- in memory, and will be saved to the database, but will not be present when
- the association is queried in the future. For example:
-
- .. code-block:: ruby
-
- trainer = Trainer.create!
- dog = Pet.create!(trainer: trainer, species: 'dog')
- cat = Pet.create!(trainer: trainer, species: 'cat')
-
- trainer.pets #=> [dog, cat]
-
- trainer.reload.pets #=> [dog]
-
-.. note::
-
- Mongoid's syntax for scoped association differs from that of ActiveRecord.
- Mongoid uses the ``:scope`` keyword argument for consistency with other
- association options, whereas in ActiveRecord the scope is a positional
- argument.
-
-
-Validations
------------
-
-It is important to note that by default, Mongoid will validate the children of any
-association that are loaded into memory via a ``validates_associated``. The associations that
-this applies to are:
-
-- ``embeds_many``
-- ``embeds_one``
-- ``has_many``
-- ``has_one``
-- ``has_and_belongs_to_many``
-
-If you do not want this behavior, you may turn it off when defining the association.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- embeds_many :addresses, validate: false
- has_many :posts, validate: false
- end
-
-
-Polymorphism
-------------
-
-One to one and one to many associations support polymorphism, which is
-having a single association potentially contain objects of different classes.
-For example, we could model an organization in which departments and teams
-have managers as follows:
-
-.. code-block:: ruby
-
- class Department
- include Mongoid::Document
-
- has_one :manager, as: :unit
- end
-
- class Team
- include Mongoid::Document
-
- has_one :manager, as: :unit
- end
-
- class Manager
- include Mongoid::Document
-
- belongs_to :unit, polymorphic: true
- end
-
- dept = Department.create!
- team = Team.create!
-
- alice = Manager.create!(unit: dept)
- alice.unit == dept
- # => true
- dept.manager == alice
- # => true
-
-To provide another example, suppose we want to track price history for
-products and bundles. This can be achieved via an embedded one to many
-polymorphic association:
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
-
- field :name, type: String
- has_and_belongs_to_many :bundles
-
- embeds_many :prices, as: :item
- end
-
- class Bundle
- include Mongoid::Document
-
- field :name, type: String
- has_and_belongs_to_many :products
-
- embeds_many :prices, as: :item
- end
-
- class Price
- include Mongoid::Document
-
- embedded_in :item, polymorphic: true
- end
-
- pants = Product.create!(name: 'Pants',
- prices: [Price.new, Price.new])
- costume = Bundle.create!(name: 'Costume', products: [pants],
- prices: [Price.new, Price.new])
-
-To define a polymorphic association, specify the ``polymorphic: true`` option
-on the child association and add the ``as: :association_name`` option to the
-parent association.
-
-Note that Mongoid currently supports polymorphism only in one direction - from
-the child to the parent. For example, polymorphism cannot be used to specify
-that a bundle may contain other bundles or products:
-
-.. code-block:: ruby
-
- class Bundle
- include Mongoid::Document
-
- # Does not work:
- has_many :items, polymorphic: true
- end
-
-``has_and_belongs_to_many`` associations do not support polymorphism.
-
-
-Cascading Callbacks
--------------------
-
-If you want the embedded document callbacks to fire when calling a persistence
-operation on its parent, you will need to provide the cascade callbacks option
-to the association.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :albums, cascade_callbacks: true
- embeds_one :label, cascade_callbacks: true
- end
-
- band.save # Fires all save callbacks on the band, albums, and label.
-
-
-.. _dependent-behavior:
-
-Dependent Behavior
-------------------
-
-You can provide dependent options to referenced associations to instruct Mongoid
-how to handle situations where one side of the association is deleted, or is attempted
-to be deleted. The options are as follows:
-
-- ``:delete_all``: Delete the child document(s) without running any of the model callbacks.
-- ``:destroy``: Destroy the child document(s) and run all of the model callbacks.
-- ``:nullify``: Set the foreign key field of the child document to nil. The child may become orphaned if it is ordinarily only referenced via the parent.
-- ``:restrict_with_exception``: ``raise`` an error if the child is not empty.
-- ``:restrict_with_error``: Cancel operation and return false if the child is not empty.
-
-If no ``:dependent`` option is provided, deleting the parent document leaves the child document unmodified
-(in other words, the child document continues to reference the now deleted parent document via the foreign key field).
-The child may become orphaned if it is ordinarily only referenced via the parent.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- has_many :albums, dependent: :delete_all
- belongs_to :label, dependent: :nullify
- end
-
- class Album
- include Mongoid::Document
- belongs_to :band
- end
-
- class Label
- include Mongoid::Document
- has_many :bands, dependent: :restrict_with_exception
- end
-
- label = Label.first
- label.bands.push(Band.first)
- label.delete # Raises an error since bands is not empty.
-
- Band.first.destroy # Will delete all associated albums.
-
-
-Autosaving
-----------
-
-One core difference between Mongoid and ActiveRecord is that Mongoid does not
-automatically save associated documents for referenced (i.e., non-embedded)
-associations when the parent is saved, for performance reasons.
-
-If autosaving is not used, it is possible to create dangling references
-to non-existent documents via associations:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_many :albums
- end
-
- class Album
- include Mongoid::Document
-
- belongs_to :band
- end
-
- band = Band.new
- album = Album.create!(band: band)
-
- # The band is not persisted at this point.
-
- album.reload
-
- album.band_id
- # => BSON::ObjectId('6257699753aefe153121a3d5')
-
- # Band does not exist.
- album.band
- # => nil
-
-To make referenced associations save automatically when the parent is saved,
-add the ``:autosave`` option to the association:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- has_many :albums
- end
-
- class Album
- include Mongoid::Document
-
- belongs_to :band, autosave: true
- end
-
- band = Band.new
- album = Album.create!(band: band)
-
- # The band is persisted at this point.
-
- album.reload
-
- album.band_id
- # => BSON::ObjectId('62576b4b53aefe178b65b8e3')
-
- album.band
- # => #
-
-The autosaving functionality is automatically added to an association when
-using ``accepts_nested_attributes_for``, so that the application does not
-need to track which associations were modified when processing a form
-submission.
-
-Embedded associations always autosave, because they are stored as part of the
-parent document.
-
-Some operations on associations always save the parent and the child documents
-as part of the operation, regardless of whether autosaving is enabled.
-A non-exhaustive list of these operations is as follows:
-
-- Assignment to the association:
-
- .. code-block:: ruby
-
- # Saves the band and the album.
- band.albums = [Album.new]
-
-- ``push``, ``<<``:
-
- .. code-block:: ruby
-
- band.albums << Album.new
- band.albums.push(Album.new)
-
-
-Existence Predicates
---------------------
-
-All associations have existence predicates on them in the form of ``name?`` and ``has_name?``
-to check if the association is blank.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_one :label
- embeds_many :albums
- end
-
- band.label?
- band.has_label?
- band.albums?
- band.has_albums?
-
-Autobuilding
-------------
-
-One to one associations (``embeds_one``, ``has_one``) have an autobuild option which tells
-Mongoid to instantiate a new document when the association is accessed and it is ``nil``.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_one :label, autobuild: true
- has_one :producer, autobuild: true
- end
-
- band = Band.new
- band.label # Returns a new empty label.
- band.producer # Returns a new empty producer.
-
-Touching
---------
-Any ``belongs_to`` association can take an optional ``:touch`` option which
-will cause the parent document to be touched whenever the child document is
-updated:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name
- belongs_to :label, touch: true
- end
-
- band = Band.first
- band.name = "The Rolling Stones"
- band.save! # Calls touch on the parent label.
- band.touch # Calls touch on the parent label.
-
-``:touch`` can also take a string or symbol argument specifying a field to
-be touched on the parent association in addition to updated_at:
-
-.. code-block:: ruby
-
- class Label
- include Mongoid::Document
- include Mongoid::Timestamps
- field :bands_updated_at, type: Time
- has_many :bands
- end
-
- class Band
- include Mongoid::Document
- belongs_to :label, touch: :bands_updated_at
- end
-
- label = Label.create!
- band = Band.create!(label: label)
-
- band.touch # Updates updated_at and bands_updated_at on the label.
-
-When an embedded document is touched, its parents are recursively touched
-through the composition root (because all of the parents are necessarily saved
-when the embedded document is saved). The ``:touch`` attribute therefore is
-unnecessary on ``embedded_in`` associations.
-
-Mongoid currently `does not support specifying an additional field to be
-touched on an embedded_in association `_.
-
-``:touch`` should not be set to ``false`` on an ``embedded_in`` association,
-since composition hierarchy is always updated upon a touch of an embedded
-document. This is currently not enforced but enforcement is `intended in the
-future `_.
-
-The counter_cache Option
-------------------------
-
-As with ActiveRecord, the ``:counter_cache`` option can be used on an association
-to make finding the number of belonging objects more efficient. Also similar
-to ActiveRecord, you must take into account that there will be an extra
-attribute on the associated model. This means that with Mongoid,
-you need to include ``Mongoid::Attributes::Dynamic`` on the associated model.
-For example:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
- belongs_to :customer, counter_cache: true
- end
-
- class Customer
- include Mongoid::Document
- include Mongoid::Attributes::Dynamic
- has_many :orders
- end
-
-Association Proxies
--------------------
-
-Associations employ transparent proxies to the target objects. This can
-cause surprising behavior in some situations.
-
-The method visibility may be lost when methods on association targets are
-accessed, depending on the association:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
- belongs_to :customer
-
- private
-
- def internal_status
- 'new'
- end
- end
-
- class Customer
- include Mongoid::Document
- has_many :orders
-
- private
-
- def internal_id
- 42
- end
- end
-
- order = Order.new
- customer = Customer.create!(orders: [order])
-
- # has_many does not permit calling private methods on the target
- customer.orders.first.internal_status
- # NoMethodError (private method `internal_status' called for #)
-
- # belongs_to permits calling private methods on the target
- order.customer.internal_id
- # => 42
-
-Association Metadata
-====================
-
-All associations in Mongoid contain metadata that holds information about the association in
-question, and is a valuable tool for third party developers to use to extend Mongoid.
-
-You can access the association metadata of the association in a few different ways.
-
-.. code-block:: ruby
-
- # Get the metadata for a named association from the class or document.
- Model.reflect_on_association(:association_name)
- model.reflect_on_association(:association_name)
-
- # Get the metadata with a specific association itself on a specific
- # document.
- model.associations[:association_name]
-
-Attributes
-----------
-
-All associations contain a ``_target``, which is the proxied document or documents, a ``_base``
-which is the document the association hangs off, and ``_association`` which provides information
-about the association.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- embeds_many :addresses
- end
-
- person.addresses = [ address ]
- person.addresses._target # returns [ address ]
- person.addresses._base # returns person
- person.addresses._association # returns the association metadata
-
-The Association Object
-----------------------
-
-The association object itself contains more information than one might know what to do
-with, and is useful for developers of extensions to Mongoid.
-
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Method
- - Description
- * - ``Association#as``
- - Returns the name of the parent to a polymorphic child.
- * - ``Association#as?``
- - Returns whether or not an as option exists.
- * - ``Association#autobuilding?``
- - Returns whether or not the association is autobuilding.
- * - ``Association#autosaving?``
- - Returns whether or not the association is autosaving.
- * - ``Association#cascading_callbacks?``
- - Returns whether the association has callbacks cascaded down from the parent.
- * - ``Association#class_name``
- - Returns the class name of the proxied document.
- * - ``Association#cyclic?``
- - Returns whether the association is a cyclic association.
- * - ``Association#dependent``
- - Returns the association's dependent option.
- * - ``Association#destructive?``
- - Returns true if the association has a dependent delete or destroy.
- * - ``Association#embedded?``
- - Returns whether the association is embedded in another document.
- * - ``Association#forced_nil_inverse?``
- - Returns whether the association has a nil inverse defined.
- * - ``Association#foreign_key``
- - Returns the name of the foreign key field.
- * - ``Association#foreign_key_check``
- - Returns the name of the foreign key field dirty check method.
- * - ``Association#foreign_key_setter``
- - Returns the name of the foreign key field setter.
- * - ``Association#indexed?``
- - Returns whether the foreign key is auto indexed.
- * - ``Association#inverses``
- - Returns the names of all inverse association.
- * - ``Association#inverse``
- - Returns the name of a single inverse association.
- * - ``Association#inverse_class_name``
- - Returns the class name of the association on the inverse side.
- * - ``Association#inverse_foreign_key``
- - Returns the name of the foreign key field on the inverse side.
- * - ``Association#inverse_klass``
- - Returns the class of the association on the inverse side.
- * - ``Association#inverse_association``
- - Returns the metadata of the association on the inverse side.
- * - ``Association#inverse_of``
- - Returns the explicitly defined name of the inverse association.
- * - ``Association#inverse_setter``
- - Returns the name of the method used to set the inverse.
- * - ``Association#inverse_type``
- - Returns the name for the polymorphic type field of the inverse.
- * - ``Association#inverse_type_setter``
- - Returns the name for the polymorphic type field setter of the inverse.
- * - ``Association#key``
- - Returns the name of the field in the attributes hash to use to get the association.
- * - ``Association#klass``
- - Returns the class of the proxied documents in the association.
- * - ``Association#name``
- - Returns the association name.
- * - ``Association#options``
- - Returns self, for API compatibility with ActiveRecord.
- * - ``Association#order``
- - Returns the custom sorting options on the association.
- * - ``Association#polymorphic?``
- - Returns whether the association is polymorphic.
- * - ``Association#setter``
- - Returns the name of the field to set the association.
- * - ``Association#store_as``
- - Returns the name of the attribute to store an embedded association in.
- * - ``Association#touchable?``
- - Returns whether or not the association has a touch option.
- * - ``Association#type``
- - Returns the name of the field to get the polymorphic type.
- * - ``Association#type_setter``
- - Returns the name of the field to set the polymorphic type.
- * - ``Association#validate?``
- - Returns whether the association has an associated validation.
diff --git a/docs/reference/callbacks.txt b/docs/reference/callbacks.txt
deleted file mode 100644
index 972451dd0b..0000000000
--- a/docs/reference/callbacks.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-.. _callbacks:
-
-*********
-Callbacks
-*********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Mongoid implements many of the `ActiveRecord callbacks
-`_.
-
-
-Document Callbacks
-==================
-
-Mongoid supports the following callbacks for :doc:`documents `:
-
-- ``after_initialize``
-- ``after_build``
-- ``before_validation``
-- ``after_validation``
-- ``before_create``
-- ``around_create``
-- ``after_create``
-- ``after_find``
-- ``before_update``
-- ``around_update``
-- ``after_update``
-- ``before_upsert``
-- ``around_upsert``
-- ``after_upsert``
-- ``before_save``
-- ``around_save``
-- ``after_save``
-- ``before_destroy``
-- ``around_destroy``
-- ``after_destroy``
-
-Callbacks are available on any document, whether it is embedded within
-another document or not. Note that to be efficient, Mongoid only invokes
-the callback on the document that the persistence action was executed on.
-This enables Mongoid to support large hierarchies and to handle optimized
-atomic updates efficiently (without invoking callbacks throughout the document
-hierarchy).
-
-Note that using callbacks for domain logic is a bad design practice, and can
-lead to unexpected errors that are hard to debug when callbacks in
-the chain halt execution. It is our recommendation to only use them
-for cross-cutting concerns, like queueing up background jobs.
-
-.. code-block:: ruby
-
- class Article
- include Mongoid::Document
- field :name, type: String
- field :body, type: String
- field :slug, type: String
-
- before_create :send_message
-
- after_save do |document|
- # Handle callback here.
- end
-
- protected
- def send_message
- # Message sending code here.
- end
- end
-
-Callbacks are coming from Active Support, so you can use the new
-syntax as well:
-
-.. code-block:: ruby
-
- class Article
- include Mongoid::Document
- field :name, type: String
-
- set_callback(:create, :before) do |document|
- # Message sending code here.
- end
- end
-
-
-Association Callbacks
-=====================
-
-Mongoid has a set of callbacks that are specific to associations - these are:
-
-- ``after_add``
-- ``after_remove``
-- ``before_add``
-- ``before_remove``
-
-Each time a document is added or removed from any of the following
-associations, the respective callbacks are invoked: ``embeds_many``,
-``has_many`` and ``has_and_belongs_to_many``.
-
-Association callbacks are specified as options on the respective association.
-The document added/removed will be passed as the parameter to the specified
-callback. Example:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- has_many :posts, after_add: :send_email_to_subscribers
- end
-
- def send_email_to_subscribers(post)
- Notifications.new_post(post).deliver
- end
diff --git a/docs/reference/collection-configuration.txt b/docs/reference/collection-configuration.txt
deleted file mode 100644
index 26bea0162b..0000000000
--- a/docs/reference/collection-configuration.txt
+++ /dev/null
@@ -1,107 +0,0 @@
-.. _collection_configuration:
-
-************************
-Collection Configuration
-************************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Configuring a Document Collection
-=================================
-
-You can specify collection options for documents using the ``store_in`` macro.
-This macro accepts ``:collection_options`` argument, which can contain any collection
-options that are supported by the driver.
-
-.. note::
-
- In order to apply the options, the collection must be explicitly created up-front.
- This should be done using :ref:`Collection Management Rake Task`.
-
-Please refer to `the driver collections page
-`_
-for the more information about collection options.
-
-.. note::
-
- Collection options depend on the driver version and MongoDB server version.
- It is possible that some options, like time series collections, are not available
- on older server versions.
-
-Time Series Collection
-----------------------
-
-.. code-block:: ruby
-
- class Measurement
- include Mongoid::Document
-
- field :temperature, type: Integer
- field :timestamp, type: Time
-
- store_in collection_options: {
- time_series: {
- timeField: "timestamp",
- granularity: "minutes"
- },
- expire_after: 604800
- }
- end
-
-
-
-Capped Collections
-------------------
-
-.. code-block:: ruby
-
- class Name
- include Mongoid::Document
-
- store_in collection_options: {
- capped: true,
- size: 1024
- }
- end
-
-Set a Default Collation on a Collection
----------------------------------------
-
-.. code-block:: ruby
-
- class Name
- include Mongoid::Document
-
- store_in collection_options: {
- collation: {
- locale: 'fr'
- }
- }
- end
-
-.. _collection-management-task:
-
-Collection Management Rake Task
-===============================
-
-If you specify collection options for a document, then the corresponding collection
-must be explicitly created prior to use. To do so, use the provided
-``db:mongoid:create_collections`` Rake task:
-
-.. code-block:: bash
-
- $ rake db:mongoid:create_collections
-
-The create collections command also works for just one model by running
-in Rails console:
-
-.. code-block:: ruby
-
- # Create collection for Model
- Model.create_collection
diff --git a/docs/reference/compatibility.txt b/docs/reference/compatibility.txt
deleted file mode 100644
index fa15c8fabb..0000000000
--- a/docs/reference/compatibility.txt
+++ /dev/null
@@ -1,470 +0,0 @@
-.. _compatibility:
-
-*************
-Compatibility
-*************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Ruby MongoDB Driver Compatibility
-=================================
-
-The following compatibility table specifies the versions of `Ruby driver for
-MongoDB `_
-(the ``mongo`` gem) supported by the most recent patch releases of the
-specified Mongoid versions.
-
-.. note::
-
- Older versions of Mongoid within the same minor release may support older
- driver versions. For example, Mongoid 7.0.5 supports driver versions 2.5 and
- newer, whereas Mongoid 7.0.6 requires driver version 2.7 or newer.
-
-.. list-table::
- :header-rows: 1
- :stub-columns: 1
- :class: compatibility-large no-padding
-
- * - Mongoid
- - Driver 2.19-2.18
- - Driver 2.17-2.10
- - Driver 2.9-2.7
-
- * - 8.0 thru 9.0
- - |checkmark|
- -
- -
-
- * - 7.2 thru 7.5
- - |checkmark|
- - |checkmark|
- -
-
- * - 7.0 thru 7.1
- - |checkmark|
- - |checkmark|
- - |checkmark|
-
-
-Ruby Compatibility
-==================
-
-The following compatibility table specifies the versions of Ruby interpreters
-supported by Mongoid. "D" in a column means support for that Ruby version
-is deprecated.
-
-.. list-table::
- :header-rows: 1
- :stub-columns: 1
- :class: compatibility-large no-padding
-
- * - Mongoid
- - Ruby 3.2
- - Ruby 3.1
- - Ruby 3.0
- - Ruby 2.7
- - Ruby 2.6
- - Ruby 2.5
- - Ruby 2.4
- - Ruby 2.3
- - Ruby 2.2
- - JRuby 9.4
- - JRuby 9.3
- - JRuby 9.2
-
- * - 9.0
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
- -
- -
- -
- - |checkmark|
- -
- -
-
- * - 8.1
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
- -
- -
- -
- - |checkmark|
- -
-
- * - 8.0
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
- -
- -
- -
- - |checkmark|
- -
-
- * - 7.5
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - D
- -
- -
- -
- -
- - |checkmark|
- - D
-
- * - 7.4
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
- -
- -
- -
- - |checkmark|
-
- * - 7.3
- -
- - |checkmark| [#mongoid-7.3-ruby-3.0]_
- - |checkmark| [#mongoid-7.3-ruby-3.0]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - D
- - D
- -
- -
- -
- - |checkmark|
-
- * - 7.2
- -
- - |checkmark| [#mongoid-7.2-ruby-3.0]_
- - |checkmark| [#mongoid-7.2-ruby-3.0]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - D
- - D
- -
- -
- -
- - |checkmark|
-
- * - 7.1
- -
- - |checkmark| [#mongoid-7.1-ruby-3.0]_
- - |checkmark| [#mongoid-7.1-ruby-3.0]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark| [#ruby-2.4]_
- - |checkmark|
- -
- -
- -
- - |checkmark|
-
- * - 7.0
- -
- -
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark| [#ruby-2.4]_
- - |checkmark|
- - |checkmark| [#ruby-2.2]_
- -
- -
- - |checkmark|
-
-.. [#mongoid-7.3-ruby-3.0] Mongoid version 7.3.2 or higher is required.
-
-.. [#mongoid-7.2-ruby-3.0] Mongoid version 7.2.5 or higher is required.
-
-.. [#mongoid-7.1-ruby-3.0] Mongoid version 7.1.10 or higher is required.
-
-.. [#ruby-2.4] Ruby version 2.4.1 or higher is required.
-
-.. [#ruby-2.2] Ruby version 2.2.2 or higher is required.
-
-
-MongoDB Server Compatibility
-============================
-
-The following compatibility table specifies the recommended
-version(s) of Mongoid for use with a specific version of MongoDB server.
-
-Note that in order to use features of a particular MongoDB server version,
-both the driver and Mongoid must support that server version.
-Please refer to `the driver compatibility page
-`_
-for driver compatibility matrices.
-
-"D" in a column means support for that MongoDB server version is deprecated
-and will be removed in a next version.
-
-.. list-table::
- :header-rows: 1
- :stub-columns: 1
- :class: compatibility-large no-padding
-
- * - Mongoid
- - MongoDB 7.0
- - MongoDB 6.0
- - MongoDB 5.0
- - MongoDB 4.4
- - MongoDB 4.2
- - MongoDB 4.0
- - MongoDB 3.6
- - MongoDB 3.4
- - MongoDB 3.2
- - MongoDB 3.0
- - MongoDB 2.6
-
- * - 8.0 thru 9.0
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
- -
- -
-
- * - 7.4 thru 7.5
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - D
- - D
- - D
- - D
-
- * - 7.0 thru 7.3
- -
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - D
- - D
- - D
- - D
-
-
-.. _rails-compatibility:
-
-Rails Compatibility
-===================
-
-The following compatibility table specifies which versions of Ruby on Rails
-are supported by Mongoid.
-
-.. list-table::
- :header-rows: 1
- :stub-columns: 1
- :class: compatibility-large no-padding
-
- * - Mongoid
- - Rails 7.1
- - Rails 7.0
- - Rails 6.1
- - Rails 6.0
- - Rails 5.2
- - Rails 5.1
-
- * - 9.0
- - |checkmark| [#rails-7.1]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
- -
- -
-
- * - 8.0 thru 8.1
- - |checkmark| [#rails-7.1]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark| [#rails-5-ruby-3.0]_
- -
-
- * - 7.5
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark| [#rails-5-ruby-3.0]_
- - D
-
- * - 7.4
- -
- - |checkmark|
- - |checkmark|
- - |checkmark|
- - |checkmark| [#rails-5-ruby-3.0]_
- - |checkmark| [#rails-5-ruby-3.0]_
-
- * - 7.3
- -
- - |checkmark| [#rails-7-Mongoid-7.3]_
- - |checkmark|
- - |checkmark|
- - |checkmark| [#rails-5-ruby-3.0]_
- - |checkmark| [#rails-5-ruby-3.0]_
-
- * - 7.2
- -
- -
- - |checkmark| [#rails-6.1]_
- - |checkmark|
- - |checkmark| [#rails-5-ruby-3.0]_
- - |checkmark| [#rails-5-ruby-3.0]_
-
- * - 7.1
- -
- -
- - |checkmark| [#rails-6.1]_
- - |checkmark|
- - |checkmark|
- - |checkmark|
-
- * - 7.0
- -
- -
- - |checkmark| [#rails-6.1]_
- - |checkmark| [#rails-6]_
- - |checkmark|
- - |checkmark|
-
-.. [#rails-5-ruby-3.0] Using Rails 5.x with Ruby 3 is not supported.
-
-.. [#rails-6] Rails 6.0 requires Mongoid 7.0.5 or later.
-
-.. [#rails-6.1] Rails 6.1 requires Mongoid 7.0.12, 7.1.7 or 7.2.1 in the
- respective 7.0, 7.1 and 7.2 stable branches.
-
-.. [#rails-7-Mongoid-7.3] Rails 7.x requires Mongoid 7.3.4 or later.
-
-.. [#rails-7.1] Rails 7.1 requires Mongoid 8.0.7 or 8.1.3 in the respective
- 8.0 and 8.1 stable branches.
-
-.. include:: /includes/unicode-checkmark.rst
-.. include:: /includes/unicode-ballot-x.rst
-
-Rails Frameworks Support
-------------------------
-
-Ruby on Rails is comprised of a number of frameworks, which Mongoid attempts to
-provide compatibility with wherever possible.
-
-Though Mongoid attempts to offer API compatibility with `Active Record `_,
-libraries that depend directly on Active Record may not work as expected when
-Mongoid is used as a drop-in replacement.
-
-.. note::
-
- Mongoid can be used alongside Active Record within the same application without issue.
-
-.. list-table::
- :header-rows: 1
- :stub-columns: 1
- :class: compatibility-large no-padding
-
- * - Rails Framework
- - Supported?
-
- * - ``ActionCable``
- - |checkmark| [#rails-actioncable-dependency]_
-
- * - ``ActionMailbox``
- - |x| [#rails-activerecord-dependency]_
-
- * - ``ActionMailer``
- - |checkmark|
-
- * - ``ActionPack``
- - |checkmark|
-
- * - ``ActionText``
- - |x| [#rails-activerecord-dependency]_
-
- * - ``ActionView``
- - |checkmark|
-
- * - ``ActiveJob``
- - |checkmark| [#rails-activejob-dependency]_
-
- * - ``ActiveModel``
- - |checkmark| [#rails-activemodel-dependency]_
-
- * - ``ActiveStorage``
- - |x| [#rails-activerecord-dependency]_
-
- * - ``ActiveSupport``
- - |checkmark| [#rails-activesupport-dependency]_
-
-.. [#rails-actioncable-dependency] There is currently no MongoDB adapter for
- ``ActionCable``, however any existing adapter (such as `Redis `_)
- can be used successfully in conjunction with Mongoid models
-
-.. [#rails-activerecord-dependency] Depends directly on ``ActiveRecord``
-
-.. [#rails-activemodel-dependency] ``Mongoid::Document`` includes ``ActiveModel::Model``
- and leverages ``ActiveModel::Validations`` for validations
-
-.. [#rails-activesupport-dependency] ``Mongoid`` requires ``ActiveSupport`` and
- uses it extensively, including ``ActiveSupport::TimeWithZone`` for time handling.
-
-
-
-.. [#rails-activejob-dependency] Serialization of BSON & Mongoid objects works best
- if you explicitly send ``BSON::ObjectId``'s as strings, and reconstitute them in the job:
-
- .. code-block:: ruby
-
- record = Model.find(...)
- MyJob.perform_later(record._id.to_s)
-
- class MyJob < ApplicationJob
- def perform(id_as_string)
- record = Model.find(id_as_string)
- # ...
- end
- end
diff --git a/docs/reference/configuration.txt b/docs/reference/configuration.txt
deleted file mode 100644
index 2d82faf24a..0000000000
--- a/docs/reference/configuration.txt
+++ /dev/null
@@ -1,1027 +0,0 @@
-.. _configuration:
-
-*************
-Configuration
-*************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Mongoid is customarily configured through a ``mongoid.yml`` file that specifies
-options and clients. The simplest configuration is as follows, which configures
-Mongoid to talk to a MongoDB server at "localhost:27017" and use the database
-named "mongoid".
-
-.. code-block:: yaml
-
- development:
- clients:
- default:
- database: mongoid
- hosts:
- - localhost:27017
-
-The top level key in the configuration file, ``development`` in the above
-example, refers to the environment name which the application is executing in,
-i.e. ``development``, ``test`` or ``production``. The third level key,
-``default`` in the above example, refers to the Mongo client name.
-Most applications will use a single client named ``default``.
-
-
-Generating Default Configuration
-================================
-
-If you are using Ruby on Rails, you can have Mongoid generate a default
-configuration file for you by running the following command:
-
-.. code-block:: bash
-
- rails g mongoid:config
-
-The configuration file will be placed in ``config/mongoid.yml``. An
-initializer will also be created and placed in
-``config/initializers/mongoid.rb``. It is recommended that all configuration
-be specified in ``config/mongoid.yml``, but if you prefer, the ``mongoid.rb``
-initializer may also be used to set configuration options. Note, though, that
-settings in ``mongoid.yml`` always take precedence over settings in the
-initializer.
-
-If you are not using Ruby on Rails, you can copy the minimal configuration
-given above and save it as ``config/mongoid.yml``.
-
-
-Loading Mongoid Configuration
-=============================
-
-If you are using Ruby on Rails, Mongoid configuration is automatically loaded
-for the current environment as stored in ``Rails.env`` when the application
-loads.
-
-You may need to configure the ORM for your application to be Mongoid by
-adding the following to ``application.rb``:
-
-.. code-block:: ruby
-
- config.generators do |g|
- g.orm :mongoid
- end
-
-If you are not using Ruby on Rails, Mongoid configuration must be loaded
-manually. This can be done via the ``Mongoid.load!`` method, which takes
-the configuration file path as its argument, as follows:
-
-.. code-block:: ruby
-
- # Use automatically detected environment name
- Mongoid.load!("path/to/your/mongoid.yml")
-
- # Specify environment name manually
- Mongoid.load!("path/to/your/mongoid.yml", :production)
-
-When Mongoid is asked to automatically detect the environment name,
-it does so by examining the following sources, in order:
-
-- If ``Rails`` top level constant is defined, ``Rails.env``.
-- If ``Sinatra`` top level constant is defined, ``Sinatra::Base.environment``.
-- The ``RACK_ENV`` environment variable.
-- The ``MONGOID_ENV`` environment variable.
-
-It is also possible to configure Mongoid directly in Ruby, without using
-a configuration file. This configuration style does not support the concept
-of environments - whatever configuration is provided, it is applied to the
-current environment - but it does support defining multiple clients.
-
-.. code-block:: ruby
-
- Mongoid.configure do |config|
- config.clients.default = {
- hosts: ['localhost:27017'],
- database: 'my_db',
- }
-
- config.log_level = :warn
- end
-
-.. note::
-
- Mongoid must be configured *before* any component of it is used or referenced.
- Once a component is used or referenced, changing configuration may not apply
- changes to already instantiated components.
-
-
-.. _configuration-options:
-
-Mongoid Configuration Options
-=============================
-
-The following annotated example ``mongoid.yml`` demonstrates how Mongoid
-can be configured.
-
-Mongoid delegates to the Ruby driver for client configuration. Please review
-`the driver documentation `_
-for details on driver options.
-
-.. code-block:: yaml
-
- development:
- # Configure available database clients. (required)
- clients:
- # Defines the default client. (required)
- default:
- # Mongoid can connect to a URI accepted by the driver:
- # uri: mongodb://user:password@mongodb.domain.com:27017/my_db_development
-
- # Otherwise define the parameters separately.
- # This defines the name of the default database that Mongoid can connect to.
- # (required).
- database: my_db_development
- # Provides the hosts the default client can connect to. Must be an array
- # of host:port pairs. (required)
- hosts:
- - localhost:27017
- options:
- # Note that all options listed below are Ruby driver client options (the mongo gem).
- # Please refer to the driver documentation of the version of the mongo gem you are using
- # for the most up-to-date list of options.
-
- # Change the default write concern. (default = { w: 1 })
- # write:
- # w: 1
-
- # Change the default read preference. Valid options for mode are: :secondary,
- # :secondary_preferred, :primary, :primary_preferred, :nearest
- # (default: primary)
- # read:
- # mode: :secondary_preferred
- # tag_sets:
- # - use: web
-
- # The name of the user for authentication.
- # user: 'user'
-
- # The password of the user for authentication.
- # password: 'password'
-
- # The user's database roles.
- # roles:
- # - 'dbOwner'
-
- # Change the default authentication mechanism. Valid options include:
- # :scram, :scram256, :mongodb_cr, :mongodb_x509, :gssapi, :aws, :plain.
- # MongoDB Server defaults to :scram, which will use "SCRAM-SHA-256" if available,
- # otherwise fallback to "SCRAM-SHA-1" (:scram256 will always use "SCRAM-SHA-256".)
- # This setting is handled by the MongoDB Ruby Driver. Please refer to:
- # https://mongodb.com/docs/ruby-driver/current/reference/authentication/
- # auth_mech: :scram
-
- # The database or source to authenticate the user against.
- # (default: the database specified above or admin)
- # auth_source: admin
-
- # Force a the driver cluster to behave in a certain manner instead of auto-
- # discovering. Can be one of: :direct, :replica_set, :sharded. Set to :direct
- # when connecting to hidden members of a replica set.
- # connect: :direct
-
- # Changes the default time in seconds the server monitors refresh their status
- # via hello commands. (default: 10)
- # heartbeat_frequency: 10
-
- # The time in seconds for selecting servers for a near read preference. (default: 0.015)
- # local_threshold: 0.015
-
- # The timeout in seconds for selecting a server for an operation. (default: 30)
- # server_selection_timeout: 30
-
- # The maximum number of connections in the connection pool. (default: 5)
- # max_pool_size: 5
-
- # The minimum number of connections in the connection pool. (default: 1)
- # min_pool_size: 1
-
- # The time to wait, in seconds, in the connection pool for a connection
- # to be checked in before timing out. (default: 5)
- # wait_queue_timeout: 5
-
- # The time to wait to establish a connection before timing out, in seconds.
- # (default: 10)
- # connect_timeout: 10
-
- # How long to wait for a response for each operation sent to the
- # server. This timeout should be set to a value larger than the
- # processing time for the longest operation that will be executed
- # by the application. Note that this is a client-side timeout;
- # the server may continue executing an operation after the client
- # aborts it with the SocketTimeout exception.
- # (default: nil, meaning no timeout)
- # socket_timeout: 5
-
- # The name of the replica set to connect to. Servers provided as seeds that do
- # not belong to this replica set will be ignored.
- # replica_set: name
-
- # Compressors to use for wire protocol compression. (default is to not use compression)
- # "zstd" requires zstd-ruby gem. "snappy" requires snappy gem.
- # Refer to: https://www.mongodb.com/docs/ruby-driver/current/reference/create-client/#compression
- # compressors: ["zstd", "snappy", "zlib"]
-
- # Whether to connect to the servers via ssl. (default: false)
- # ssl: true
-
- # The certificate file used to identify the connection against MongoDB.
- # ssl_cert: /path/to/my.cert
-
- # The private keyfile used to identify the connection against MongoDB.
- # Note that even if the key is stored in the same file as the certificate,
- # both need to be explicitly specified.
- # ssl_key: /path/to/my.key
-
- # A passphrase for the private key.
- # ssl_key_pass_phrase: password
-
- # Whether to do peer certification validation. (default: true)
- # ssl_verify: true
-
- # The file containing concatenated certificate authority certificates
- # used to validate certs passed from the other end of the connection.
- # ssl_ca_cert: /path/to/ca.cert
-
- # Whether to truncate long log lines. (default: true)
- # truncate_logs: true
-
- # Configure Mongoid-specific options. (optional)
- options:
- # Allow BSON::Decimal128 to be parsed and returned directly in
- # field values. When BSON 5 is present and the this option is set to false
- # (the default), BSON::Decimal128 values in the database will be returned
- # as BigDecimal.
- #
- # @note this option only has effect when BSON 5+ is present. Otherwise,
- # the setting is ignored.
- # allow_bson5_decimal128: false
-
- # Application name that is printed to the MongoDB logs upon establishing
- # a connection. Note that the name cannot exceed 128 bytes in length.
- # It is also used as the database name if the database name is not
- # explicitly defined. (default: nil)
- # app_name: nil
-
- # When this flag is false, callbacks for embedded documents will not be
- # called. This is the default in 9.0.
- #
- # Setting this flag to true restores the pre-9.0 behavior, where callbacks
- # for embedded documents are called. This may lead to stack overflow errors
- # if there are more than cicrca 1000 embedded documents in the root
- # document's dependencies graph.
- # See https://jira.mongodb.org/browse/MONGOID-5658 for more details.
- # around_callbacks_for_embeds: false
-
- # Sets the async_query_executor for the application. By default the thread pool executor
- # is set to `:immediate`. Options are:
- #
- # - :immediate - Initializes a single +Concurrent::ImmediateExecutor+
- # - :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
- # that uses the +async_query_concurrency+ for the +max_threads+ value.
- # async_query_executor: :immediate
-
- # Mark belongs_to associations as required by default, so that saving a
- # model with a missing belongs_to association will trigger a validation
- # error.
- # belongs_to_required_by_default: true
-
- # Set the global discriminator key.
- # discriminator_key: "_type"
-
- # Raise an exception when a field is redefined.
- # duplicate_fields_exception: false
-
- # Defines how many asynchronous queries can be executed concurrently.
- # This option should be set only if `async_query_executor` is set
- # to `:global_thread_pool`.
- # global_executor_concurrency: nil
-
- # When this flag is true, any attempt to change the _id of a persisted
- # document will raise an exception (`Errors::ImmutableAttribute`).
- # This is the default in 9.0. Setting this flag to false restores the
- # pre-9.0 behavior, where changing the _id of a persisted
- # document might be ignored, or it might work, depending on the situation.
- # immutable_ids: true
-
- # Include the root model name in json serialization.
- # include_root_in_json: false
-
- # # Include the _type field in serialization.
- # include_type_for_serialization: false
-
- # Whether to join nested persistence contexts for atomic operations
- # to parent contexts by default.
- # join_contexts: false
-
- # When this flag is false (the default as of Mongoid 9.0), a document that
- # is created or loaded will remember the storage options that were active
- # when it was loaded, and will use those same options by default when
- # saving or reloading itself.
- #
- # When this flag is true you'll get pre-9.0 behavior, where a document will
- # not remember the storage options from when it was loaded/created, and
- # subsequent updates will need to explicitly set up those options each time.
- #
- # For example:
- #
- # record = Model.with(collection: 'other_collection') { Model.first }
- #
- # This will try to load the first document from 'other_collection' and
- # instantiate it as a Model instance. Pre-9.0, the record object would
- # not remember that it came from 'other_collection', and attempts to
- # update it or reload it would fail unless you first remembered to
- # explicitly specify the collection every time.
- #
- # As of Mongoid 9.0, the record will remember that it came from
- # 'other_collection', and updates and reloads will automatically default
- # to that collection, for that record object.
- # legacy_persistence_context_behavior: false
-
- # When this flag is false, a document will become read-only only once the
- # #readonly! method is called, and an error will be raised on attempting
- # to save or update such documents, instead of just on delete. When this
- # flag is true, a document is only read-only if it has been projected
- # using #only or #without, and read-only documents will not be
- # deletable/destroyable, but they will be savable/updatable.
- # When this feature flag is turned on, the read-only state will be reset on
- # reload, but when it is turned off, it won't be.
- # legacy_readonly: false
-
- # The log level.
- #
- # It must be set prior to referencing clients or Mongo.logger,
- # changes to this option are not be propagated to any clients and
- # loggers that already exist.
- #
- # Additionally, only when the clients are configured via the
- # configuration file is the log level given by this option honored.
- # log_level: :info
-
- # Store BigDecimals as Decimal128s instead of strings in the db.
- # map_big_decimal_to_decimal128: true
-
- # Preload all models in development, needed when models use inheritance.
- # preload_models: false
-
- # When this flag is true, callbacks for every embedded document will be
- # called only once, even if the embedded document is embedded in multiple
- # documents in the root document's dependencies graph.
- # This is the default in 9.0. Setting this flag to false restores the
- # pre-9.0 behavior, where callbacks are called for every occurrence of an
- # embedded document. The pre-9.0 behavior leads to a problem that for multi
- # level nested documents callbacks are called multiple times.
- # See https://jira.mongodb.org/browse/MONGOID-5542
- # prevent_multiple_calls_of_embedded_callbacks: true
-
- # Raise an error when performing a #find and the document is not found.
- # raise_not_found_error: true
-
- # Raise an error when defining a scope with the same name as an
- # existing method.
- # scope_overwrite_exception: false
-
- # Return stored times as UTC.
- # use_utc: false
-
- # Configure Driver-specific options. (optional)
- driver_options:
- # When this flag is off, an aggregation done on a view will be executed over
- # the documents included in that view, instead of all documents in the
- # collection. When this flag is on, the view filter is ignored.
- # broken_view_aggregate: true
-
- # When this flag is set to false, the view options will be correctly
- # propagated to readable methods.
- # broken_view_options: true
-
- # When this flag is set to true, the update and replace methods will
- # validate the parameters and raise an error if they are invalid.
- # validate_update_replace: false
-
-
-.. _load-defaults:
-
-Version Based Defaults
-======================
-
-Mongoid supports setting the configuration options to the defaults for specific
-versions. This is useful for upgrading to a new Mongoid version. When upgrading
-your Mongoid version, the following should be set on ``Mongoid::Config``:
-
-.. code:: ruby
-
- Mongoid.configure do |config|
- config.load_defaults
- end
-
-This way, when upgrading to a new version of Mongoid, your code will run with
-the configuration options from the previous version of Mongoid. Then,
-one-by-one, you can change the feature flags for the new version, and test that
-your code still acts as expected. Once all of the new feature flags have been
-accounted for, the call to ``load_defaults`` may be changed to take in the *new*
-version, and all of the changed feature flags may be removed.
-
-For example, suppose we're upgrading from 7.5 to 8.0. Between these two versions,
-two feature flags were added: ``legacy_attributes`` and ``map_big_decimal_to_decimal128``.
-Before upgrading to Mongoid 8, add the following to your ``Mongoid::Config``:
-
-.. code:: ruby
-
- Mongoid.configure do |config|
- config.load_defaults 7.5
- end
-
-After upgrading to Mongoid 8.0 in your ``Gemfile``, any feature flags will
-remain set to their 7.5 default behavior: ``legacy_attributes: true,
-map_big_decimal_to_decimal128: false``. You may then flip these feature flags
-one-by-one to their 8.0 behavior:
-
-.. code:: ruby
-
- Mongoid.configure do |config|
- config.load_defaults 7.5
- config.legacy_attributes = false
- # config.map_big_decimal_to_decimal128 = true
- end
-
-We recommend do these one at a time, so in the example above we leave the
-second flag commented out. After verifying your code works as expected with the
-``legacy_attributes`` flag turned off, the ``map_big_decimal_to_decimal128``
-setting can be uncommented. Once that functionality is verified as well, both
-of those lines can be removed and the ``load_defaults`` replaced with:
-
-.. code:: ruby
-
- Mongoid.configure do |config|
- config.load_defaults 8.0
- end
-
-
-ERb Preprocessing
-=================
-
-When loading a configuration file, Mongoid processes it with ERb before
-parsing it as YAML. This allows, for example, constructing the contents of
-the configuration file at runtime based on environment variables:
-
-.. code-block:: yaml
-
- development:
- clients:
- default:
- uri: "<%= ENV['MONGODB_URI'] %>"
-
-.. note::
-
- When outputting values from ERb, ensure the values are valid YAML and
- escape them as needed.
-
-.. note::
-
- Since ERb rendering is performed prior to YAML parsing, all ERb directives
- in the configuration file are evaluated, including those occurring in YAML
- comments.
-
-Logging
-=======
-
-When configuring logging, it is important to keep in mind that Mongoid
-provides a model layer on top of the MongoDB Ruby driver, and the driver
-dispatches the CRUD operations to the MongoDB deployment. Therefore, some
-of the logging output in an application using Mongoid comes from Mongoid
-itself, and some comes from the driver.
-
-The Mongo client is a Ruby driver client instance, therefore
-the logger of a Mongo client is the Ruby driver logger, not the Mongoid
-logger. In other words:
-
-.. code-block:: ruby
-
- # Ruby driver logger, not Mongoid logger
- Mongoid.client(:default).logger
-
-Depending on whether Mongoid is used in a Ruby on Rails application, and how
-both Mongoid and Ruby driver are configured, they may use the same logger
-instance or different instances, potentially with different configurations.
-
-In Ruby on Rails Application
-----------------------------
-
-When used in a Ruby on Rails application, Mongoid by default inherits
-the logger and the log level from Rails, and sets the driver's logger
-to the same logger instance:
-
-.. code-block:: ruby
-
- Rails.logger === Mongoid.logger
- # => true
-
- Mongoid.logger === Mongo::Logger.logger
- # => true
-
-To change the log level, use `standard Rails configuration
-`_.
-Place the following in one of environment configuration files, such as
-``config/environments/production.rb``:
-
-.. code-block:: ruby
-
- Rails.application.configure do
- config.log_level = :debug
- end
-
-.. note::
-
- The ``log_level`` Mongoid configuration option is not used when Mongoid operates
- in a Rails application, because Mongoid inherits Rails' log level in this case.
-
-To configure either Mongoid or driver logger differently from the Rails logger,
-use an initializer as follows:
-
-.. code-block:: ruby
-
- Rails.application.configure do
- config.after_initialize do
- # Change Mongoid log destination and/or level
- Mongoid.logger = Logger.new(STDERR).tap do |logger|
- logger.level = Logger::DEBUG
- end
-
- # Change driver log destination and/or level
- Mongo::Logger.logger = Logger.new(STDERR).tap do |logger|
- logger.level = Logger::DEBUG
- end
- end
- end
-
-.. note::
-
- There is currently no provision in the Ruby standard library ``Logger``
- to return the log device (i.e. the ``IO`` object) that a logger is using.
- To have, for example, Mongoid and/or the Ruby driver log to the
- standard Rails log file (e.g. ``log/development.log``) but with a
- different level from standard Rails logger (``Rails.logger``), the
- file must be opened separately and the resulting ``IO`` object passed to
- the ``Logger`` constructor.
-
-.. note::
-
- Since by default Mongoid sets its own logger and the driver's logger to the
- same instance as the Rails logger, modifying any of the instances affects
- all of them. For example the following changes log level for all three
- loggers, unless the application assigned a separate ``Logger`` instance
- to ``Mongo::Logger.logger`` as described above:
-
- .. code-block:: ruby
-
- Mongoid::Logger.logger.level = Logger::DEBUG
-
-Standalone
-----------
-
-When not loaded in a Ruby on Rails application, Mongoid respects the
-``log_level`` top level configuration option. It can be given in the
-configuration file as follows:
-
-.. code-block:: yaml
-
- development:
- clients:
- default:
- # ...
- options:
- log_level: :debug
-
-... or when configuring Mongoid inline:
-
-.. code-block:: ruby
-
- Mongoid.configure do |config|
- config.log_level = :debug
- end
-
-The default log destination in Mongoid 7.1 and higher is standard error.
-The default log destination in Mongoid 7.0 and lower is standard output.
-To change the log destination, create a new logger instance as follows:
-
-.. code-block:: ruby
-
- Mongoid.logger = Logger.new(STDERR).tap do |logger|
- logger.level = Logger::DEBUG
- end
-
-To change the Ruby driver log level or destination:
-
-.. code-block:: ruby
-
- Mongo::Logger.logger = Logger.new(STDERR).tap do |logger|
- logger.level = Logger::DEBUG
- end
-
-To set the driver logger to be the same as the Mongoid logger:
-
-.. code-block:: ruby
-
- Mongo::Logger.logger = Mongoid.logger
-
-.. note::
-
- Mongoid does not alter the driver's logger when running in
- standalone mode.
-
-.. _time-zones:
-
-Time Zones
-==========
-
-Mongoid uses ActiveSupport's time zone functionality, which is far
-more robust than Ruby's standard library. Importantly, ActiveSupport
-allows configuration of ``Time.zone``, a thread-global variable which
-provides context for working with date and time values.
-
-While a thorough treatment of time zones in Ruby is outside the scope
-of this tutorial, the easiest and most reliable way of achieving correct
-time zone handling is as follows:
-
-1. Set the operating system's time zone to UTC. For example, on Linux:
-
-.. code-block:: bash
-
- cp /usr/share/zoneinfo/UTC /etc/localtime
-
-2. Set your application default time zone to UTC:
-
-.. code-block:: ruby
-
- # If using Rails, in application.rb:
- class Application < Rails::Application
- config.time_zone = 'UTC'
- end
-
- # If not using Rails:
- Time.zone = 'UTC'
-
-3. In each controller and job class, set the appropriate time zone in a
- ``before_filter`` at the earliest possible stage. As an example,
- if each user of your application can set their own time zone,
- you may wish to do:
-
-.. code-block:: ruby
-
- class ApplicationController < ActionController::Base
- before_filter :fetch_user,
- :set_time_zone
-
- def set_time_zone
- Time.zone = @user.time_zone
- end
- end
-
-4. From here, you may work with times naturally in the local time zone.
- For example, in a view:
-
-.. code-block:: ruby
-
- Turned into a pumpkin after <%= cinderella.updated_at.seconds_after_midnight %> seconds!
-
-5. Use ActiveSupport methods instead of the Ruby standard library.
-
- - ``Time.zone.now`` or ``Time.current` instead of ``Time.now``
- - ``Date.current`` instead of ``Date.today``
-
- Critically, note that the latter Ruby standard library methods reference
- your system time zone (e.g. UTC) and not the value of ``Time.zone``.
- As it is very easy to mistake these similarly named methods, we recommend to
- use `Rubocop's Rails/TimeZone cop
- `_ in your CI.
-
-Setting time zone on data loaded from MongoDB
----------------------------------------------
-
-MongoDB stores all times in UTC without time zone information.
-Mongoid models load and returns time values as instances of
-``ActiveSupport::TimeWithZone``. You may set the ``use_utc`` option
-to control how Mongoid sets the time zone when loading from the database:
-
-- If false (default), Mongoid will use ``Time.zone`` to set the time
- zone of time values are loaded from database.
-- If true, Mongoid will always set the time zone as UTC on loaded
- time values.
-
-``use_utc`` only affects how data is loaded, and does not affect
-how data is persisted. For example, if you assign a ``Time`` or
-``ActiveSupport::TimeWithZone`` instance to a time field, the time
-zone information of the assigned instance always will be used
-irrespective of the ``use_utc`` setting. Alternatively, if you
-assign a string value to a time field, any time zone information
-in the string will be used if present. If the string does not include
-time zone information it will be parsed according to ``Time.zone``.
-To illustrate:
-
-.. code-block:: ruby
-
- Time.use_zone("Asia/Kolkata") do
-
- # String does not include time zone, so "Asia/Kolkata" will be used
- ghandi.born_at = "1869-10-02 7:10 PM"
-
- # Time zone in string (-0600) will be used
- amelia.born_at = "1897-07-24 11:30 -0600"
- end
-
-
-Configuring ``SSLContext``
-==========================
-It may be desirable to further configure TLS options in your application, for
-example by enabling or disabling certain ciphers.
-
-This can be done by setting TLS context hooks on the Ruby driver -- TLS context
-hooks are user-provided ``Proc``\(s) that will be invoked before any TLS socket
-connection in the driver and can be used to modify the underlying
-``OpenSSL::SSL::SSLContext`` object used by the socket.
-
-To set TLS context hooks, add ``Proc``\(s) to the ``Mongo.tls_context_hooks``
-array. This can be done in an initializer. The example below adds a hook
-that only enables the "AES256-SHA" cipher.
-
-.. code-block:: ruby
-
- Mongo.tls_context_hooks.push(
- Proc.new { |context|
- context.ciphers = ["AES256-SHA"]
- }
- )
-
- # Only the AES256-SHA cipher will be enabled from this point forward
-
-Every ``Proc`` in ``Mongo.tls_context_hooks`` will be passed an
-``OpenSSL::SSL::SSLContext`` object as its sole argument. These procs will
-be executed sequentially during socket creation.
-
-.. warning::
-
- TLS context hooks are global and will affect all ``Mongo::Client`` instances
- in an application.
-
-For more information about TLS context hooks, including best practices for
-assigning and removing them, see `the Ruby driver documentation `_.
-
-
-Network Compression
-===================
-
-Mongoid supports compression of messages to and from MongoDB servers. This functionality is provided by
-the Ruby driver, which implements the three algorithms that are supported by MongoDB servers:
-
-- `Snappy `_: ``snappy`` compression
- can be used when connecting to MongoDB servers starting with the 3.4 release,
- and requires the `snappy `_ library to be
- installed.
-- `Zlib `_: ``zlib`` compression can be used when
- connecting to MongoDB servers starting with the 3.6 release.
-- `Zstandard `_: ``zstd`` compression can be
- used when connecting to MongoDB servers starting with the 4.2 release, and
- requires the `zstd-ruby `_ library to
- be installed.
-
-To use wire protocol compression, configure the Ruby driver options within ``mongoid.yml``:
-
-.. code-block:: yaml
-
- development:
- # Configure available database clients. (required)
- clients:
- # Define the default client. (required)
- default:
- # ...
- options:
- # These options are Ruby driver options, documented in
- # https://mongodb.com/docs/ruby-driver/current/reference/create-client/
- # ...
- # Compressors to use. (default is to not use compression)
- # Valid values are zstd, zlib or snappy - or any combination of the three
- compressors: ["zstd", "snappy"]
-
-If no compressors are explicitly requested, the driver will not use compression,
-even if the required dependencies for one or more compressors are present on the
-system.
-
-The driver chooses the first compressor of the ones requested that is also supported
-by the server. The ``zstd`` compressor is recommended as it produces the highest
-compression at the same CPU consumption compared to the other compressors.
-
-For maximum server compatibility all three compressors can be specified, e.g.
-as ``compressors: ["zstd", "snappy", "zlib"]``.
-
-
-Client-Side Encryption
-======================
-
-When loading the configuration file, Mongoid permits the file to contain
-``BSON::Binary`` instances which are used for specifying ``keyId`` in
-the schema map for `client-side encryption
-`_,
-as the following example shows:
-
-.. code-block:: yaml
-
- development:
- clients:
- default:
- database: blog_development
- hosts: [localhost:27017]
- options:
- auto_encryption_options:
- key_vault_namespace: 'keyvault.datakeys'
- kms_providers:
- local:
- key: "z7iYiYKLuYymEWtk4kfny1ESBwwFdA58qMqff96A8ghiOcIK75lJGPUIocku8LOFjQuEgeIP4xlln3s7r93FV9J5sAE7zg8U"
- schema_map:
- blog_development.comments:
- properties:
- message:
- encrypt:
- keyId:
- - !ruby/object:BSON::Binary
- data: !binary |-
- R/AgNcxASFiiJWKXqWGo5w==
- type: :uuid
- bsonType: "string"
- algorithm: "AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic"
- bsonType: "object"
-
-
-Usage with Forking Servers
-==========================
-
-When using Mongoid with a forking web server such as Puma, or any application
-that otherwise forks to spawn child processes, special considerations apply.
-
-If possible, we recommend to not perform any MongoDB operations in the parent
-process prior to forking, which will avoid any forking-related pitfalls.
-
-A detailed technical explanation of how the Mongo Ruby Driver handles forking
-is given in the `driver's "Usage with Forking Servers" documentation
-`.
-In a nutshell, to avoid various connection errors such as ``Mongo::Error::SocketError``
-and ``Mongo::Error::NoServerAvailable``, you must do the following:
-
-1. Disconnect MongoDB clients in the parent Ruby process immediately *before*
- forking using ``Mongoid.disconnect_clients``. This ensures the parent and child
- process do not accidentally reuse the same sockets and have I/O conflicts.
- Note that ``Mongoid.disconnect_clients`` does not disrupt any in-flight
- MongoDB operations, and will automatically reconnect when you perform new
- operations.
-2. Reconnect your MongoDB clients in the child Ruby process immediately *after*
- forking using ``Mongoid.reconnect_clients``. This is required to respawn
- the driver's monitoring threads in the child process.
-
-Most web servers provide hooks that can be used by applications to
-perform actions when the worker processes are forked. The following
-are configuration examples for several common Ruby web servers.
-
-Puma
-----
-
-Use the ``on_worker_boot`` hook to reconnect clients in the workers and
-the ``before_fork`` and ``on_refork`` hooks to close clients in the
-parent process (`Puma documentation `_).
-
-.. code-block:: ruby
-
- # config/puma.rb
-
- # Runs in the Puma master process before it forks a child worker.
- before_fork do
- Mongoid.disconnect_clients
- end
-
- # Required when using Puma's fork_worker option. Runs in the
- # child worker 0 process before it forks grandchild workers.
- on_refork do
- Mongoid.disconnect_clients
- end
-
- # Runs in each Puma child process after it forks from its parent.
- on_worker_boot do
- Mongoid.reconnect_clients
- end
-
-Unicorn
--------
-
-Use the ``after_fork`` hook to reconnect clients in the workers and
-the ``before_fork`` hook to close clients in the parent process
-(`Unicorn documentation `_):
-
-.. code-block:: ruby
-
- # config/unicorn.rb
-
- before_fork do |_server, _worker|
- Mongoid.disconnect_clients
- end
-
- after_fork do |_server, _worker|
- Mongoid.reconnect_clients
- end
-
-Passenger
----------
-
-Use the ``starting_worker_process`` hook to reconnect clients in the workers
-(`Passenger documentation
-`_).
-Passenger does not appear to have a hook that is invoked in the parent process
-before the workers are forked.
-
-.. code-block:: ruby
-
- if defined?(PhusionPassenger)
- PhusionPassenger.on_event(:starting_worker_process) do |forked|
- Mongoid.reconnect_clients if forked
- end
- end
-
-
-.. _query-cache-middleware:
-
-Query Cache Middleware
-======================
-
-Enabling Query Cache for Rack Web Requests
-------------------------------------------
-
-The MongoDB Ruby Driver provides a Rack middleware which enables the :ref:`Query Cache
-` for the duration of each web request. Below is an example of
-how to enable the Query Cache Middleware in a Ruby on Rails application:
-
-.. code-block:: ruby
-
- # config/application.rb
-
- # Add Mongo::QueryCache::Middleware at the bottom of the middleware stack
- # or before other middleware that queries MongoDB.
- config.middleware.use Mongo::QueryCache::Middleware
-
-Please refer to the `Rails on Rack guide
-`_
-for more information about using Rack middleware in Rails applications.
-
-Enabling Query Cache for ActiveJob
-----------------------------------
-
-The MongoDB Ruby Driver also provides Query Cache middleware for ActiveJob.
-You may enable it for all jobs in an initializer:
-
-.. code-block:: ruby
-
- # config/initializers/active_job.rb
-
- # Enable Mongo driver query cache for ActiveJob
- ActiveSupport.on_load(:active_job) do
- include Mongo::QueryCache::Middleware::ActiveJob
- end
-
-Or for a specific job class:
-
-.. code-block:: ruby
-
- class MyJob < ActiveJob::Base
- include Mongo::QueryCache::Middleware::ActiveJob
- end
-
-
-Development Configuration
-=========================
-
-Driver's default configuration is suitable for production deployment.
-In development, some settings can be adjusted to provide a better developer
-experience.
-
-- ``:server_selection_timeout``: set this to a low value (e.g., ``1``)
- if your MongoDB server is running locally and you start it manually. A low
- server selection timeout will cause the driver to fail quickly when there is
- no server running.
-
-Sample recommended development configuration:
-
-.. code-block:: yaml
-
- development:
- clients:
- default:
- database: mongoid
- hosts:
- - localhost:27017
- options:
- server_selection_timeout: 1
diff --git a/docs/reference/crud.txt b/docs/reference/crud.txt
deleted file mode 100644
index ff70fa6f5f..0000000000
--- a/docs/reference/crud.txt
+++ /dev/null
@@ -1,1074 +0,0 @@
-.. _crud:
-
-***************
-CRUD Operations
-***************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Saving Documents
-================
-
-Mongoid supports all expected CRUD operations for those familiar with other
-Ruby mappers like Active Record or Data Mapper. What distinguishes Mongoid
-from other mappers for MongoDB is that the general persistence operations
-perform atomic updates on only the fields that have changed instead of
-writing the entire document to the database each time.
-
-The persistence sections will provide examples on what database operation is
-performed when executing the documented command.
-
-Standard
---------
-
-Mongoid's standard persistence methods come in the form of common methods you
-would find in other mapping frameworks. The following table shows all standard
-operations with examples.
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Operation
- - Example
-
- * - ``Model#attributes``
-
- *Returns the document's attributes as a ``Hash`` with string keys, and
- its values in Mongoized form (i.e. the way they are stored in the db).*
-
- *The attributes hash also contains the attributes of all embedded
- documents, as well as their embedded documents, etc. If an embedded
- association is empty, its key will not show up in the returned hash.*
-
- -
- .. code-block:: ruby
-
- person = Person.new(first_name: "Heinrich", last_name: "Heine")
-
- person.attributes
- # => { "_id" => BSON::ObjectId('633467d03282a43784c2d56e'), "first_name" => "Heinrich", "last_name" => "Heine" }
-
- * - ``Model.create!``
-
- *Insert a document or multiple documents into the database, raising an
- error if a validation or server error occurs.*
-
- *Pass a hash of attributes to create one document with the specified
- attributes, or an array of hashes to create multiple documents.
- If a single hash is passed, the corresponding document is returned.
- If an array of hashes is passed, an array of documents corresponding
- to the hashes is returned.*
-
- *If a block is given to* ``create!`` *, it will be invoked with each
- document as the argument in turn prior to attempting to save that
- document.*
-
- *If there is a problem saving any of the documents, such as
- a validation error or a server error, an exception is raised
- and, consequently, none of the documents are returned.
- However, if an array of hashes was passed and previous documents were
- successfully saved, those documents will remain in the database.*
- -
- .. code-block:: ruby
-
- Person.create!(
- first_name: "Heinrich",
- last_name: "Heine"
- ) # => Person instance
-
- Person.create!([
- { first_name: "Heinrich", last_name: "Heine" },
- { first_name: "Willy", last_name: "Brandt" }
- ]) # => Array of two Person instances
-
- Person.create!(first_name: "Heinrich") do |doc|
- doc.last_name = "Heine"
- end # => Person instance
-
- * - ``Model.create``
-
- *Instantiate a document or multiple documents and, if validations pass,
- insert them into the database.*
-
- ``create`` *is similar to* ``create!`` *but does not raise
- exceptions on validation errors. It still raises errors on server
- errors, such as trying to insert a document with an* ``_id`` *that
- already exists in the collection.*
-
- *If any validation errors are encountered, the respective document
- is not inserted but is returned along with documents that were inserted.
- Use* ``persisted?`` *,* ``new_record?`` *or* ``errors`` *methods
- to check which of the returned documents were inserted into the
- database.*
- -
- .. code-block:: ruby
-
- Person.create(
- first_name: "Heinrich",
- last_name: "Heine"
- ) # => Person instance
-
- Person.create([
- { first_name: "Heinrich", last_name: "Heine" },
- { first_name: "Willy", last_name: "Brandt" }
- ]) # => Array of two Person instances
-
- Person.create(first_name: "Heinrich") do |doc|
- doc.last_name = "Heine"
- end # => Person instance
-
- class Post
- include Mongoid::Document
-
- validates_uniqueness_of :title
- end
-
- posts = Post.create([{title: "test"}, {title: "test"}])
- # => array of two Post instances
- posts.map { |post| post.persisted? } # => [true, false]
-
- * - ``Model#save!``
-
- *Save the changed attributes to the database atomically, or insert the document if
- new. Raises an exception if validations fail or there is a server error.*
-
- *Returns true if the changed attributes were saved, raises an exception otherwise.*
- -
- .. code-block:: ruby
-
- person = Person.new(
- first_name: "Heinrich",
- last_name: "Heine"
- )
- person.save!
-
- person.first_name = "Christian Johan"
- person.save!
-
- * - ``Model#save``
-
- *Save the changed attributes to the database atomically, or insert the document
- if new.*
-
- *Returns true if the changed attributes were saved. Returns false
- if there were any validation errors. Raises an exception if
- the document passed validation but there was a server error during
- the save.*
-
- *Pass* ``validate: false`` *option to bypass validations.*
-
- *Pass* ``touch: false`` *option to ignore the updates to the updated_at
- field. If the document being save has not been previously persisted,
- this option is ignored and the created_at and updated_at fields will be
- updated with the current time.*
- -
- .. code-block:: ruby
-
- person = Person.new(
- first_name: "Heinrich",
- last_name: "Heine"
- )
- person.save
- person.save(validate: false)
- person.save(touch: false)
-
- person.first_name = "Christian Johan"
- person.save
-
- * - ``Model#update_attributes``
-
- *Update the document attributes in the database. Will return true if validation passed,
- false if not.*
- -
- .. code-block:: ruby
-
- person.update_attributes(
- first_name: "Jean",
- last_name: "Zorg"
- )
-
- * - ``Model#update_attributes!``
-
- *Update the document attributes in the database and raise an error if validation failed.*
- -
- .. code-block:: ruby
-
- person.update_attributes!(
- first_name: "Leo",
- last_name: "Tolstoy"
- )
-
- * - ``Model#update_attribute``
-
- *Update a single attribute, bypassing validations.*
- -
- .. code-block:: ruby
-
- person.update_attribute(:first_name, "Jean")
-
- * - ``Model#upsert``
-
- *Performs a MongoDB replace with upsert on the document. If the document
- exists in the database and the* ``:replace`` *option is set to true, it
- will get overwritten with the current document in the application (any
- attributes present in the database but not in the application's document
- instance will be lost). If the* ``:replace`` *option is false (default),
- the document will be updated, and any attributes not in the application's
- document will be maintained.
- If the document does not exist in the database, it will be inserted.
- Note that this only runs the* ``{before|after|around}_upsert`` *callbacks.*
- -
- .. code-block:: ruby
-
- person = Person.new(
- first_name: "Heinrich",
- last_name: "Heine"
- )
- person.upsert
- person.upsert(replace: true)
-
- * - ``Model#touch``
-
- *Update the document's updated_at timestamp, optionally with one extra
- provided time field. This will cascade the touch to all*
- ``belongs_to`` *associations of the document with the option set.
- This operation skips validations and callbacks.*
-
- *Attempting to touch a destroyed document will raise* ``FrozenError``,
- *same as if attempting to update an attribute on a destroyed
- document.*
- -
- .. code-block:: ruby
-
- person.touch
- person.touch(:audited_at)
-
- * - ``Model#delete``
-
- *Deletes the document from the database without running callbacks.*
-
- *If the document is not persisted, Mongoid will attempt to delete from
- the database any document with the same* ``_id``.
- -
- .. code-block:: ruby
-
- person.delete
-
- person = Person.create!(...)
- unsaved_person = Person.new(id: person.id)
- unsaved_person.delete
- person.reload
- # raises Mongoid::Errors::DocumentNotFound because the person was deleted
-
- * - ``Model#destroy``
-
- *Deletes the document from the database while running destroy callbacks.*
-
- *If the document is not persisted, Mongoid will attempt to delete from
- the database any document with the same* ``_id``.
- -
- .. code-block:: ruby
-
- person.destroy
-
- person = Person.create!(...)
- unsaved_person = Person.new(id: person.id)
- unsaved_person.destroy
- person.reload
- # raises Mongoid::Errors::DocumentNotFound because the person was deleted
-
- * - ``Model.delete_all``
-
- *Deletes all documents from the database without running any callbacks.*
- -
- .. code-block:: ruby
-
- Person.delete_all
-
- * - ``Model.destroy_all``
-
- *Deletes all documents from the database while running callbacks. This is a
- potentially expensive operation since all documents will be loaded into memory.*
- -
- .. code-block:: ruby
-
- Person.destroy_all
-
-Mongoid provides the following persistence-related attributes:
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Attribute
- - Example
-
-
- * - ``Model#new_record?``
-
- *Returns* ``true`` *if the model instance has not yet been saved
- to the database. Opposite of* ``persisted?``
- -
- .. code-block:: ruby
-
- person = Person.new(
- first_name: "Heinrich",
- last_name: "Heine"
- )
- person.new_record? # => true
- person.save!
- person.new_record? # => false
-
- * - ``Model#persisted?``
-
- *Returns* ``true`` *if the model instance has been saved
- to the database. Opposite of* ``new_record?``
- -
- .. code-block:: ruby
-
- person = Person.new(
- first_name: "Heinrich",
- last_name: "Heine"
- )
- person.persisted? # => false
- person.save!
- person.persisted? # => true
-
-
-Atomic
-------
-
-Mongoid exposes :manual:`MongoDB update operators `
-as methods on Mongoid documents. When these methods are used, callbacks are
-not invoked and validations are not performed. The supported update operators
-are:
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Operation
- - Example
-
- * - ``Model#add_to_set``
-
- *Performs an atomic $addToSet on the field.*
- -
- .. code-block:: ruby
-
- person.add_to_set(aliases: "Bond")
-
- * - ``Model#bit``
-
- *Performs an atomic $bit on the field.*
- -
- .. code-block:: ruby
-
- person.bit(age: { and: 10, or: 12 })
-
- * - ``Model#inc``
-
- *Performs an atomic $inc on the field.*
- -
- .. code-block:: ruby
-
- person.inc(age: 1)
-
- * - ``Model#pop``
-
- *Performs an atomic $pop on the field.*
- -
- .. code-block:: ruby
-
- person.pop(aliases: 1)
-
- * - ``Model#pull``
-
- *Performs an atomic $pull on the field.*
- -
- .. code-block:: ruby
-
- person.pull(aliases: "Bond")
-
- * - ``Model#pull_all``
-
- *Performs an atomic $pullAll on the field.*
- -
- .. code-block:: ruby
-
- person.pull_all(aliases: [ "Bond", "James" ])
-
- * - ``Model#push``
-
- *Performs an atomic $push on the field.*
- -
- .. code-block:: ruby
-
- person.push(aliases: ["007","008"])
-
- * - ``Model#rename``
-
- *Performs an atomic $rename on the field.*
- -
- .. code-block:: ruby
-
- person.rename(bday: :dob)
-
- * - ``Model#set``
-
- *Updates an attribute on the model instance and, if the instance
- is already persisted, performs an atomic $set on the field, bypassing
- validations.*
-
- ``set`` *can also deeply set values on Hash fields.*
-
- ``set`` *can also deeply set values on* ``embeds_one`` *associations.
- If such an association's document is nil, one will be created prior
- to the update.*
-
- ``set`` *should not be used with* ``has_one`` *associations, as it
- does not correctly work in such cases.*
-
- -
- .. code-block:: ruby
-
- person = Person.create!(name: "Ricky Bobby")
- person.set(name: "Tyler Durden") # updates name in the database
-
-
- person = Person.new
- person.set(name: "Tyler Durden") # does not write to database
- person.name # => "Tyler Durden"
- person.persisted? # => true
-
-
- class Post
- include Mongoid::Document
-
- field :metadata, type: Hash
- end
-
- post = Post.create!
- post.set('metadata.published_at' => Time.now)
- post.metadata['published_at'] # => Time instance
-
- post.set('metadata.approved.today' => true)
- post.metadata['approved'] # => {'today' => true}
-
-
- class Flight
- include Mongoid::Document
-
- embeds_one :plan
- end
-
- class Plan
- include Mongoid::Document
-
- embedded_in :flight
-
- field :route, type: String
- end
-
- flight = Flight.create!
- flight.plan # => nil
- flight.set('plan.route', 'test route')
- flight.plan # => Plan instance
- flight.plan.route # => "test route"
-
-
- * - ``Model#unset``
-
- *Performs an atomic $unset on the field.*
- -
- .. code-block:: ruby
-
- person.unset(:name)
-
-Note that, because these methods skip validations, it is possible to both
-save invalid documents into the database and end up with invalid documents
-in the application (which would subsequently fail to save via a ``save``
-call due to the failing validations).
-
-
-.. _atomic-operation-grouping:
-
-Atomic Operation Grouping
-`````````````````````````
-
-Atomic operations may be grouped together using the ``#atomically`` method
-on a document. All operations inside the block given to ``#atomically``
-are sent to the cluster in a single atomic command. For example:
-
-.. code-block:: ruby
-
- person.atomically do
- person.inc(age: 1)
- person.set(name: 'Jake')
- end
-
-``#atomically`` blocks may be nested. The default behavior is to write
-changes performed by each block as soon as the block ends:
-
-.. code-block:: ruby
-
- person.atomically do
- person.atomically do
- person.inc(age: 1)
- person.set(name: 'Jake')
- end
- raise 'An exception'
- # name and age changes are still persisted
- end
-
-This behavior can be changed by specifying the ``join_context: true`` option
-to ``#atomically``, or globally by setting the ``join_contexts``
-:ref:`configuration option ` to ``true``. When
-context joining is enabled, nested ``#atomically`` blocks are joined with
-the outer blocks, and only the outermost block (or the first block where
-``join_contexts`` is false) actually writes changes to the cluster.
-For example:
-
-.. code-block:: ruby
-
- person.atomically do
- person.atomically(join_context: true) do
- person.inc(age: 1)
- person.set(name: 'Jake')
- end
- raise 'An exception'
- # name and age changes are not persisted
- end
-
-The context joining behavior can be enabled globally by default by setting
-``join_context`` option in Mongoid configuration. In this case specifying
-``join_context: false`` on an ``#atomically`` block can be used to
-obtain the independent persistence context behavior.
-
-If an exception is raised in an ``#atomically`` block which has not yet
-persisted its changes to the cluster, any pending attribute changes on
-Mongoid models are reverted. For example:
-
-.. code-block:: ruby
-
- person = Person.new(name: 'Tom')
- begin
- person.atomically do
- person.inc(age: 1)
- person.set(name: 'Jake')
- person.name # => 'Jake'
- raise 'An exception'
- end
- rescue Exception
- person.name # => 'Tom'
- end
-
-Atomic operations described in this section apply to one document at a time,
-therefore nesting ``#atomically`` blocks invoked on multiple documents does
-not make changes to the different documents be persisted atomically together.
-However, MongoDB offers :ref:`multi-document transactions `
-as of server version 4.0 which provide atomic persistence across multiple
-documents.
-
-
-Reloading
-=========
-
-Use the ``reload`` method to fetch the most recent version of a document from
-the database. Any unsaved modifications to the document's attributes are lost:
-
-.. code-block:: ruby
-
- band = Band.create!(name: 'foo')
- # => #
-
- band.name = 'bar'
- band
- # => #
-
- band.reload
- # => #
-
-When a document is reloaded, all of its embedded associations are also reloaded
-in the same query (since embedded documents are stored in the parent document
-on the server). If a document has referenced associations, the loaded
-associations' are not reloaded but their values are cleared, such that these
-associations would be loaded from the database at the next access.
-
-.. note::
-
- Some operations on associations, for example assignment, persists the new
- document. In these cases there may not be any unsaved modifications to
- revert by reloading. In the following example, the assignment of the
- empty array to the association is immediately persisted and reloading
- does not make any changes to the document:
-
- .. code-block:: ruby
-
- # Assuming band has many tours, which could be referenced:
- band = Band.create!(tours: [Tour.create!])
- # ... or embedded:
- band = Band.create!(tours: [Tour.new])
-
- # This writes the empty tour list into the database.
- band.tours = []
-
- # There are no unsaved modifications in band at this point to be reverted.
- band.reload
-
- # Returns the empty array since this is what is in the database.
- band.tours
- # => []
-
-If the model has a :ref:`shard key ` defined, the shard key value
-is included in the reloading query.
-
-If the database does not contain a matching document, Mongoid normally raises
-``Mongoid::Errors::DocumentNotFound``. However, if the configuration option
-``raise_not_found_error`` is set to ``false``, and the database does not
-contain a matching document, Mongoid replaces the current document with a newly
-created document whose attributes are set to default values. Importantly, this
-generally causes the ``_id`` of the document to change, as the following
-example demonstrates:
-
-.. code-block:: ruby
-
- band = Band.create!
- # => #
-
- Mongoid.raise_not_found_error = false
- band.destroy
-
- band.reload
- # => #
-
-For this reason, it is not recommended to use ``reload`` when
-``raise_not_found_error`` is set to ``false``.
-
-
-Reloading Unsaved Documents
----------------------------
-
-``reload`` can be called when the document has not yet been persisted.
-In this case ``reload`` performs a ``find`` query using the ``id`` value
-specified in the document (and the shard key value, if a shard key is defined):
-
-.. code-block:: ruby
-
- existing = Band.create!(name: 'Photek')
-
- # Unsaved document
- band = Band.new(id: existing.id)
- band.reload
- band.name
- # => "Photek"
-
-
-Accessing Field Values
-======================
-
-Mongoid provides several ways of accessing field values.
-
-.. note::
-
- All of the access methods described below raise
- ``Mongoid::Errors::AttributeNotLoaded`` when the field being accessed is
- :ref:`projected out `, either by virtue of not being included in
- :ref:`only ` or by virtue of being included in
- :ref:`without `. This applies to both reads and writes.
-
-
-Getters & Setters
------------------
-
-The recommended way is to use the getter and setter methods generated for
-each declared field:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :first_name
- end
-
- person = Person.new
-
- person.first_name = "Artem"
- person.first_name
- # => "Artem"
-
-To use this mechanism, each field must be explicitly declared, or the
-model class must enable :ref:`dynamic fields `.
-
-
-Custom Getters & Setters
-------------------------
-
-It is possible to explicitly define the getter and setter methods to provide
-custom behavior when reading or writing fields, for example value
-transformations or storing values under different field names. In this case
-``read_attribute`` and ``write_attribute`` methods can be used to read and
-write the values directly into the attributes hash:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- def first_name
- read_attribute(:fn)
- end
-
- def first_name=(value)
- write_attribute(:fn, value)
- end
- end
-
- person = Person.new
-
- person.first_name = "Artem"
- person.first_name
- # => "Artem"
-
- person.attributes
- # => {"_id"=>BSON::ObjectId('606477dc2c97a628cf47075b'), "fn"=>"Artem"}
-
-.. note::
-
- The custom setters are called during the assignment of
- :ref:`nested attributes `, however they are called before
- the associations are set up. Because of this, associations may not always
- be available during these methods, and it is encouraged to include checks
- for their presence whenever referring to them. :ref:`Callbacks `
- can also be used to perform operations on certain events, and associations
- will have already been setup and are available during their execution.
-
-.. _read-write-attribute:
-
-``read_attribute`` & ``write_attribute``
-----------------------------------------
-
-The ``read_attribute`` and ``write_attribute`` methods can be used explicitly
-as well. Note that if a field specifies its :ref:`storage field name
-`, both ``read_attribute`` and ``write_attribute``
-accept either the declared field name or the storage field name for operations:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :first_name, as: :fn
- field :last_name, as: :ln
- end
-
- person = Person.new(first_name: "Artem")
- # => #
-
- person.read_attribute(:first_name)
- # => "Artem"
-
- person.read_attribute(:fn)
- # => "Artem"
-
- person.write_attribute(:last_name, "Pushkin")
- person
- # => #
-
- person.write_attribute(:ln, "Medvedev")
- person
- # => #
-
-``read_attribute`` and ``write_attribute`` do not require that a field with
-the used name is defined, but writing field values with ``write_attribute``
-does not cause the respective field to be defined either:
-
-.. code-block:: ruby
-
- person.write_attribute(:undefined, "Hello")
- person
- # => #
- person.attributes
- # => {"_id"=>BSON::ObjectId('60647b212c97a6292c195b4c'), "first_name"=>"Artem", "last_name"=>"Medvedev", "undefined"=>"Hello"}
-
- person.read_attribute(:undefined)
- # => "Hello"
- person.undefined
- # raises NoMethodError
-
-When ``read_attribute`` is used to access a missing field, it returns ``nil``.
-
-
-Hash Access
------------
-
-Mongoid model instances define the ``[]`` and ``[]=`` methods to provide
-``Hash`` style access to the attributes. ``[]`` is an alias for
-``read_attribute`` and ``[]=`` is an alias for ``write_attribute``; see
-the section on :ref:`read_attribute and write_attribute `
-for the detailed description of their behavior.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :first_name, as: :fn
- field :last_name, as: :ln
- end
-
- person = Person.new(first_name: "Artem")
-
- person["fn"]
- # => "Artem"
-
- person[:first_name]
- # => "Artem"
-
- person[:ln] = "Medvedev"
- person
- # => #
-
- person["last_name"] = "Pushkin"
- person
- # => #
-
-
-Bulk Attribute Writes
----------------------
-
-In cases where you want to set multiple field values at once, there are a few
-different ways of accomplishing this as well.
-
-.. code-block:: ruby
-
- # Get the field values as a hash.
- person.attributes
-
- # Set the field values in the document.
- Person.new(first_name: "Jean-Baptiste", middle_name: "Emmanuel")
- person.attributes = { first_name: "Jean-Baptiste", middle_name: "Emmanuel" }
- person.write_attributes(
- first_name: "Jean-Baptiste",
- middle_name: "Emmanuel",
- )
-
-
-Dirty Tracking
-==============
-
-Mongoid supports tracking of changed or "dirty" fields with an API that mirrors that of
-Active Model. If a defined field has been modified in a model the model will be marked as
-dirty and some additional behavior comes into play.
-
-
-Viewing Changes
----------------
-
-There are various ways to view what has been altered on a model. Changes are recorded
-from the time a document is instantiated, either as a new document or via loading from
-the database up to the time it is saved. Any persistence operation clears the changes.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :name, type: String
- end
-
- person = Person.first
- person.name = "Alan Garner"
-
- # Check to see if the document has changed.
- person.changed? # true
-
- # Get an array of the names of the changed fields.
- person.changed # [ :name ]
-
- # Get a hash of the old and changed values for each field.
- person.changes # { "name" => [ "Alan Parsons", "Alan Garner" ] }
-
- # Check if a specific field has changed.
- person.name_changed? # true
-
- # Get the changes for a specific field.
- person.name_change # [ "Alan Parsons", "Alan Garner" ]
-
- # Get the previous value for a field.
- person.name_was # "Alan Parsons"
-
-.. note::
-
- Setting the associations on a document does not cause the ``changes`` or
- ``changed_attributes`` hashes to be modified. This is true for all associations
- whether referenced or embedded. Note that changing the _id(s) field on
- referenced associations does cause the changes to show up in the ``changes``
- and the ``changed_attributes`` hashes.
-
-
-Resetting Changes
------------------
-
-You can reset changes of a field to its previous value by calling the reset method.
-
-.. code-block:: ruby
-
- person = Person.first
- person.name = "Alan Garner"
-
- # Reset the changed name back to the original
- person.reset_name!
- person.name # "Alan Parsons"
-
-
-Persistence
------------
-
-Mongoid uses dirty tracking as the core of its persistence operations. It looks at the
-changes on a document and atomically updates only what has changed, unlike other frameworks
-that write the entire document on each save. If no changes have been made, Mongoid will
-not hit the database on a call to ``Model#save``.
-
-
-Viewing Previous Changes
-------------------------
-
-After a document has been persisted, you can see what the changes were previously by
-calling ``Model#previous_changes``.
-
-.. code-block:: ruby
-
- person = Person.first
- person.name = "Alan Garner"
- person.save # Clears out current changes.
-
- # View the previous changes.
- person.previous_changes # { "name" => [ "Alan Parsons", "Alan Garner" ] }
-
-
-Updating Container Fields
-=========================
-
-Be aware that, until
-`MONGOID-2951 `_
-is resolved, all fields including container ones must be assigned to for
-their values to be persisted to the database.
-
-For example, adding to a set like this does not work:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :tours, type: Set
- end
-
- band = Band.new
- band.tours
- # => #
-
- band.tours << 'London'
- # => #
- band.tours
- # => #
-
-Instead, the field value must be modified outside of the model and assigned
-back to the model as follows:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :tours, type: Set
- end
-
- band = Band.new
-
- tours = band.tours
- # => #
-
- tours << 'London'
- # => #
-
- band.tours = tours
- # => #
-
- band.tours
- # => #
-
-
-.. _readonly-documents:
-
-Readonly Documents
-==================
-
-Documents can be marked read-only in two ways, depending on the value of the
-``Mongoid.legacy_readonly`` feature flag:
-
-If this flag is turned off, a document is marked read-only when the ``#readonly!``
-method is called on that documnet. A read-only document, with this flag turned off,
-will raise a ReadonlyDocument error on attempting to perform any persistence
-operation, including (but not limited to) saving, updating, deleting and
-destroying. Note that reloading does not reset the read-only state.
-
-.. code:: ruby
-
- band = Band.first
- band.readonly? # => false
- band.readonly!
- band.readonly? # => true
- band.name = "The Rolling Stones"
- band.save # => raises ReadonlyDocument error
- band.reload.readonly? # => true
-
-If this flag is turned on, a document is marked read-only when that document
-has been projected (i.e. using ``#only`` or ``#without``). A read-only document,
-with this flag turned on, will not be deletable or destroyable (a
-``ReadonlyDocument`` error will be raised), but will be saveable and updatable.
-The read-only status is reset on reloading the document.
-
-.. code:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :genre, type: String
- end
-
- band = Band.only(:name).first
- band.readonly? # => true
- band.destroy # => raises ReadonlyDocument error
- band.reload.readonly? # => false
-
-
-Overriding ``readonly?``
-------------------------
-
-Another way to make a document read-only is by overriding the readonly? method:
-
-.. code:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :genre, type: String
-
- def readonly?
- true
- end
- end
-
- band = Band.first
- band.readonly? # => true
- band.destroy # => raises ReadonlyDocument error
diff --git a/docs/reference/fields.txt b/docs/reference/fields.txt
deleted file mode 100644
index 5e29bfeec4..0000000000
--- a/docs/reference/fields.txt
+++ /dev/null
@@ -1,1778 +0,0 @@
-.. _fields:
-
-****************
-Field Definition
-****************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-.. _field-types:
-
-Field Types
-===========
-
-MongoDB stores underlying document data using
-`BSON types `_, and
-Mongoid converts BSON types to Ruby types at runtime in your application.
-For example, a field defined with ``type: :float`` will use the Ruby ``Float``
-class in-memory and will persist in the database as the the BSON ``double`` type.
-
-Field type definitions determine how Mongoid behaves when constructing queries
-and retrieving/writing fields from/to the database. Specifically:
-
-1. When assigning values to fields at runtime, the values are converted to the
- specified type.
-2. When persisting data to MongoDB, the data is sent in an appropriate
- type, permitting richer data manipulation within MongoDB or by other
- tools.
-3. When querying documents, query parameters are converted to the specified
- type before being sent to MongoDB.
-4. When retrieving documents from the database, field values are converted
- to the specified type.
-
-Changing the field definitions in a model class does not alter data already stored in
-MongoDB. To update type or contents of fields of existing documents,
-the field must be re-saved to the database. Note that, due to Mongoid
-tracking which attributes on a model change and only saving the changed ones,
-it may be necessary to explicitly write a field value when changing the
-type of an existing field without changing the stored values.
-
-Consider a simple class for modeling a person in an application. A person may
-have a name, date_of_birth, and weight. We can define these attributes
-on a person by using the ``field`` macro.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :name, type: String
- field :date_of_birth, type: Date
- field :weight, type: Float
- end
-
-The valid types for fields are as follows:
-
-- ``Array``
-- ``BSON::Binary``
-- :ref:`BigDecimal `
-- ``Mongoid::Boolean``, which may be specified simply as ``Boolean`` in the
- scope of a class which included ``Mongoid::Document``.
-- :ref:`Date `
-- :ref:`DateTime `
-- ``Float``
-- :ref:`Hash `
-- ``Integer``
-- :ref:`Object `
-- ``BSON::ObjectId``
-- ``Range``
-- :ref:`Regexp `
-- ``Set``
-- ``String``
-- :ref:`Mongoid::StringifiedSymbol `,
- which may be specified simply as ``StringifiedSymbol`` in the scope of a
- class which included ``Mongoid::Document``.
-- :ref:`Symbol `
-- :ref:`Time `
-- ``ActiveSupport::TimeWithZone``
-
-Mongoid also recognizes the string ``"Boolean"`` as an alias for the
-``Mongoid::Boolean`` class.
-
-To define custom field types, refer to :ref:`Custom Field Types ` below.
-
-.. note::
-
- Using the ``BSON::Int64`` and ``BSON::Int32`` types as field types is unsupported.
- Saving these types to the database will work as expected, however, querying them
- will return the native Ruby ``Integer`` type. Querying fields of type
- ``BSON::Decimal128`` will return values of type ``BSON::Decimal128`` in
- BSON <=4 and values of type ``BigDecimal`` in BSON 5+.
-
-
-.. _untyped-fields:
-
-Untyped Fields
---------------
-
-Not specifying a type for a field is the same as specifying the ``Object``
-type. Such fields are untyped:
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
-
- field :properties
- # Equivalent to:
- field :properties, type: Object
- end
-
-An untyped field can store values of any type which is directly serializable
-to BSON. This is useful when a field may contain values of different types
-(i.e. it is a variant type field), or when the type of values is not known
-ahead of time:
-
-.. code-block:: ruby
-
- product = Product.new(properties: "color=white,size=large")
- product.properties
- # => "color=white,size=large"
-
- product = Product.new(properties: {color: "white", size: "large"})
- product.properties
- # => {:color=>"white", :size=>"large"}
-
-When values are assigned to the field, Mongoid still performs mongoization but
-uses the class of the value rather than the field type for mongoization logic.
-
-.. code-block:: ruby
-
- product = Product.new(properties: 0..10)
- product.properties
- # The range 0..10, mongoized:
- # => {"min"=>0, "max"=>10}
-
-When reading data from the database, Mongoid does not perform any type
-conversions on untyped fields. For this reason, even though it is possible
-to write any BSON-serializable value into an untyped fields, values which
-require special handling on the database reading side will generally not work
-correctly in an untyped field. Among field types supported by Mongoid,
-values of the following types should not be stored in untyped fields:
-
-- ``Date`` (values will be returned as ``Time``)
-- ``DateTime`` (values will be returned as ``Time``)
-- ``Range`` (values will be returned as ``Hash``)
-
-
-.. _field-type-stringified-symbol:
-
-Field Type: StringifiedSymbol
------------------------------
-
-The ``StringifiedSymbol`` field type is the recommended field type for storing
-values that should be exposed as symbols to Ruby applications. When using the ``Symbol`` field type,
-Mongoid defaults to storing values as BSON symbols. For more information on the
-BSON symbol type, see :ref:`here `.
-However, the BSON symbol type is deprecated and is difficult to work with in programming languages
-without native symbol types, so the ``StringifiedSymbol`` type allows the use of symbols
-while ensuring interoperability with other drivers. The ``StringifiedSymbol`` type stores all data
-on the database as strings, while exposing values to the application as symbols.
-
-An example usage is shown below:
-
-.. code-block:: ruby
-
- class Post
- include Mongoid::Document
-
- field :status, type: StringifiedSymbol
- end
-
- post = Post.new(status: :hello)
- # status is stored as "hello" on the database, but returned as a Symbol
- post.status
- # => :hello
-
- # String values can be assigned also:
- post = Post.new(status: "hello")
- # status is stored as "hello" on the database, but returned as a Symbol
- post.status
- # => :hello
-
-All non-string values will be stringified upon being sent to the database (via ``to_s``), and
-all values will be converted to symbols when returned to the application. Values that cannot be
-converted directly to symbols, such as integers and arrays, will first be converted to strings and
-then symbols before being returned to the application.
-
-For example, setting an integer as ``status``:
-
-.. code-block:: ruby
-
- post = Post.new(status: 42)
- post.status
- # => :"42"
-
-If the ``StringifiedSymbol`` type is applied to a field that contains BSON symbols, the values
-will be stored as strings instead of BSON symbols on the next save. This permits transparent lazy
-migration from fields that currently store either strings or BSON symbols in the database to the
-``StringifiedSymbol`` field type.
-
-
-.. _field-type-symbol:
-
-Field Type: Symbol
-------------------
-
-New applications should use the :ref:`StringifiedSymbol field type `
-to store Ruby symbols in the database. The ``StringifiedSymbol`` field type
-provides maximum compatibility with other applications and programming languages
-and has the same behavior in all circumstances.
-
-Mongoid also provides the deprecated ``Symbol`` field type for serializing
-Ruby symbols to BSON symbols. Because the BSON specification deprecated the
-BSON symbol type, the ``bson`` gem will serialize Ruby symbols into BSON strings
-when used on its own. However, in order to maintain backwards compatibility
-with older datasets, the ``mongo`` gem overrides this behavior to serialize Ruby
-symbols as BSON symbols. This is necessary to be able to specify queries for
-documents which contain BSON symbols as fields.
-
-To override the default behavior and configure the ``mongo`` gem (and thereby
-Mongoid as well) to encode symbol values as strings, include the following code
-snippet in your project:
-
-.. code-block:: ruby
-
- class Symbol
- def bson_type
- BSON::String::BSON_TYPE
- end
- end
-
-
-.. _field-type-hash:
-
-Field Type: Hash
-----------------
-
-When using a field of type Hash, be wary of adhering to the
-`legal key names for mongoDB `_,
-or else the values will not store properly.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :first_name
- field :url, type: Hash
-
- # will update the fields properly and save the values
- def set_vals
- self.first_name = 'Daniel'
- self.url = {'home_page' => 'http://www.homepage.com'}
- save
- end
-
- # all data will fail to save due to the illegal hash key
- def set_vals_fail
- self.first_name = 'Daniel'
- self.url = {'home.page' => 'http://www.homepage.com'}
- save
- end
- end
-
-
-.. _field-type-time:
-
-Field Type: Time
-----------------
-
-``Time`` fields store values as ``Time`` instances in the :ref:`configured
-time zone `.
-
-``Date`` and ``DateTime`` instances are converted to ``Time`` instances upon
-assignment to a ``Time`` field:
-
-.. code-block:: ruby
-
- class Voter
- include Mongoid::Document
-
- field :registered_at, type: Time
- end
-
- Voter.new(registered_at: Date.today)
- # => #
-
-In the above example, the value was interpreted as the beginning of today in
-local time, because the application was not configured to use UTC times.
-
-.. note::
-
- When the database contains a string value for a ``Time`` field, Mongoid
- parses the string value using ``Time.parse`` which considers values without
- time zones to be in local time.
-
-
-.. _field-type-date:
-
-Field Type: Date
-----------------
-
-Mongoid allows assignment of values of several types to ``Date`` fields:
-
-- ``Date`` - the provided date is stored as is.
-- ``Time``, ``DateTime``, ``ActiveSupport::TimeWithZone`` - the date component
- of the value is taken in the value's time zone.
-- ``String`` - the date specified in the string is used.
-- ``Integer``, ``Float`` - the value is taken to be a UTC timestamp which is
- converted to the :ref:`configured time zone ` (note that
- ``Mongoid.use_utc`` has no effect on this conversion), then the date is
- taken from the resulting time.
-
-In other words, if a date is specified in the value, that date is used without
-first converting the value to the configured time zone.
-
-As a date & time to date conversion is lossy (it discards the time component),
-especially if an application operates with times in different time zones it is
-recommended to explicitly convert ``String``, ``Time`` and ``DateTime``
-objects to ``Date`` objects before assigning the values to fields of type
-``Date``.
-
-.. note::
-
- When the database contains a string value for a ``Date`` field, Mongoid
- parses the string value using ``Time.parse``, discards the time portion of
- the resulting ``Time`` object and uses the date portion. ``Time.parse``
- considers values without time zones to be in local time.
-
-
-.. _field-type-date-time:
-
-Field Type: DateTime
----------------------
-
-MongoDB stores all times as UTC timestamps. When assigning a value to a
-``DateTime`` field, or when querying a ``DateTime`` field, Mongoid
-converts the passed in value to a UTC ``Time`` before sending it to the
-MongoDB server.
-
-``Time``, ``ActiveSupport::TimeWithZone`` and ``DateTime`` objects embed
-time zone information, and the value persisted is the specified moment in
-time, in UTC. When the value is retrieved, the time zone in which it is
-returned is defined by the :ref:`configured time zone settings `.
-
-.. code-block:: ruby
-
- class Ticket
- include Mongoid::Document
- field :opened_at, type: DateTime
- end
-
- Time.zone = 'Berlin'
-
- ticket = Ticket.create!(opened_at: '2018-02-18 07:00:08 -0500')
-
- ticket.opened_at
- # => Sun, 18 Feb 2018 13:00:08 +0100
- ticket
- # => #
-
- Time.zone = 'America/New_York'
- ticket.opened_at
- # => Sun, 18 Feb 2018 07:00:08 -0500
-
- Mongoid.use_utc = true
- ticket.opened_at
- # => Sun, 18 Feb 2018 12:00:08 +0000
-
-Mongoid also supports casting integers and floats to ``DateTime``. When
-doing so, the integers/floats are assumed to be Unix timestamps (in UTC):
-
-.. code-block:: ruby
-
- ticket.opened_at = 1544803974
- ticket.opened_at
- # => Fri, 14 Dec 2018 16:12:54 +0000
-
-If a string is used as a ``DateTime`` field value, the behavior depends on
-whether the string includes a time zone. If no time zone is specified,
-the :ref:`default Mongoid time zone ` is used:
-
-.. code-block:: ruby
-
- Time.zone = 'America/New_York'
- ticket.opened_at = 'Mar 4, 2018 10:00:00'
- ticket.opened_at
- # => Sun, 04 Mar 2018 15:00:00 +0000
-
-If a time zone is specified, it is respected:
-
-.. code-block:: ruby
-
- ticket.opened_at = 'Mar 4, 2018 10:00:00 +01:00'
- ticket.opened_at
- # => Sun, 04 Mar 2018 09:00:00 +0000
-
-.. note::
-
- When the database contains a string value for a ``DateTime`` field, Mongoid
- parses the string value using ``Time.parse`` which considers values without
- time zones to be in local time.
-
-
-.. _field-type-regexp:
-
-Field Type: Regexp
-------------------
-
-MongoDB supports storing regular expressions in documents, and querying using
-regular expressions. Note that MongoDB uses
-`Perl-compatible regular expressions (PCRE) `_
-and Ruby uses `Onigmo `_, which is a
-fork of `Oniguruma regular expression engine `_.
-The two regular expression implementations generally provide equivalent
-functionality but have several important syntax differences.
-
-When a field is declared to be of type Regexp, Mongoid converts Ruby regular
-expressions to BSON regular expressions and stores the result in MongoDB.
-Retrieving the field from the database produces a ``BSON::Regexp::Raw``
-instance:
-
-.. code-block:: ruby
-
- class Token
- include Mongoid::Document
-
- field :pattern, type: Regexp
- end
-
- token = Token.create!(pattern: /hello.world/m)
- token.pattern
- # => /hello.world/m
-
- token.reload
- token.pattern
- # => #
-
-Use ``#compile`` method on ``BSON::Regexp::Raw`` to get back the Ruby regular
-expression:
-
-.. code-block:: ruby
-
- token.pattern.compile
- # => /hello.world/m
-
-Note that, if the regular expression was not originally a Ruby one, calling
-``#compile`` on it may produce a different regular expression. For example,
-the following is a PCRE matching a string that ends in "hello":
-
-.. code-block:: ruby
-
- BSON::Regexp::Raw.new('hello$', 's')
- # => #
-
-Compiling this regular expression produces a Ruby regular expression that
-matches strings containing "hello" before a newline, besides strings ending in
-"hello":
-
-.. code-block:: ruby
-
- BSON::Regexp::Raw.new('hello$', 's').compile =~ "hello\nworld"
- # => 0
-
-This is because the meaning of ``$`` is different between PCRE and Ruby
-regular expressions.
-
-.. _field-type-big-decimal:
-
-BigDecimal Fields
------------------
-
-The ``BigDecimal`` field type is used to store numbers with increased precision.
-
-The ``BigDecimal`` field type stores its values in two different ways in the
-database, depending on the value of the ``Mongoid.map_big_decimal_to_decimal128``
-global config option. If this flag is set to false (which is the default),
-the ``BigDecimal`` field will be stored as a string, otherwise it will be stored
-as a ``BSON::Decimal128``.
-
-The ``BigDecimal`` field type has some limitations when converting to and from
-a ``BSON::Decimal128``:
-
-- ``BSON::Decimal128`` has a limited range and precision, while ``BigDecimal``
- has no restrictions in terms of range and precision. ``BSON::Decimal128`` has
- a max value of approximately ``10^6145`` and a min value of approximately
- ``-10^6145``, and has a maximum of 34 bits of precision. When attempting to
- store values that don't fit into a ``BSON::Decimal128``, it is recommended to
- have them stored as a string instead of a ``BSON::Decimal128``. You can do
- that by setting ``Mongoid.map_big_decimal_to_decimal128`` to ``false``. If a
- value that does not fit in a ``BSON::Decimal128`` is attempted to be stored
- as one, an error will be raised.
-
-- ``BSON::Decimal128`` is able to accept signed ``NaN`` values, while
- ``BigDecimal`` is not. When retrieving signed ``NaN`` values from
- the database using the ``BigDecimal`` field type, the ``NaN`` will be
- unsigned.
-
-- ``BSON::Decimal128`` maintains trailing zeroes when stored in the database.
- ``BigDecimal``, however, does not maintain trailing zeroes, and therefore
- retrieving ``BSON::Decimal128`` values using the ``BigDecimal`` field type
- may result in a loss of precision.
-
-There is an additional caveat when storing a ``BigDecimal`` in a field with no
-type (i.e. a dynamically typed field) and ``Mongoid.map_big_decimal_to_decimal128``
-is ``false``. In this case, the ``BigDecimal`` is stored as a string, and since a
-dynamic field is being used, querying for that field with a ``BigDecimal`` will
-not find the string for that ``BigDecimal``, since the query is looking for a
-``BigDecimal``. In order to query for that string, the ``BigDecimal`` must
-first be converted to a string with ``to_s``. Note that this is not a problem
-when the field has type ``BigDecimal``.
-
-If you wish to avoid using ``BigDecimal`` altogether, you can set the field
-type to ``BSON::Decimal128``. This will allow you to keep track of trailing
-zeroes and signed ``NaN`` values.
-
-Migration to ``decimal128``-backed ``BigDecimal`` Field
-```````````````````````````````````````````````````````
-In a future major version of Mongoid, the ``Mongoid.map_big_decimal_to_decimal128``
-global config option will be defaulted to ``true``. When this flag is turned on,
-``BigDecimal`` values in queries will not match to the strings that are already
-stored in the database; they will only match to ``decimal128`` values that are
-in the database. If you have a ``BigDecimal`` field that is backed by strings,
-you have three options:
-
-1. The ``Mongoid.map_big_decimal_to_decimal128`` global config option can be
- set to ``false``, and you can continue storing your ``BigDecimal`` values as
- strings. Note that you are surrendering the advantages of storing ``BigDecimal``
- values as a ``decimal128``, like being able to do queries and aggregations
- based on the numerical value of the field.
-
-2. The ``Mongoid.map_big_decimal_to_decimal128`` global config option can be
- set to ``true``, and you can convert all values for that field from strings to
- ``decimal128`` values in the database. You should do this conversion before
- setting the global config option to true. An example query to accomplish this
- is as follows:
-
- .. code-block:: javascript
-
- db.bands.updateMany({
- "field": { "$exists": true }
- }, [
- {
- "$set": {
- "field": { "$toDecimal": "$field" }
- }
- }
- ])
-
- This query updates all documents that have the given field, setting that
- field to its corresponding ``decimal128`` value. Note that this query only
- works in MongoDB 4.2+.
-
-3. The ``Mongoid.map_big_decimal_to_decimal128`` global config option can be
- set to ``true``, and you can have both strings and ``decimal128`` values for
- that field. This way, only ``decimal128`` values will be inserted into and
- updated to the database going forward. Note that you still don't get the
- full advantages of using only ``decimal128`` values, but your dataset is
- slowly migrating to all ``decimal128`` values, as old string values are
- updated to ``decimal128`` and new ``decimal128`` values are added. With this
- setup, you can still query for ``BigDecimal`` values as follows:
-
- .. code-block:: ruby
-
- Mongoid.map_big_decimal_to_decimal128 = true
- big_decimal = BigDecimal('2E9')
- Band.in(sales: [big_decimal, big_decimal.to_s]).to_a
-
- This query will find all values that are either a ``decimal128`` value or
- a string that match that value.
-
-
-Using Symbols Or Strings Instead Of Classes
--------------------------------------------
-
-Mongoid permits using symbols or strings instead of classes to specify the
-type of fields, for example:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
-
- field :state, type: :integer
- # Equivalent to:
- field :state, type: "integer"
- # Equivalent to:
- field :state, type: Integer
- end
-
-Only standard field types as listed below can be specified using symbols or
-strings in this manner. Mongoid recognizes the following expansions:
-
-- ``:array`` => ``Array``
-- ``:big_decimal`` => ``BigDecimal``
-- ``:binary`` => ``BSON::Binary``
-- ``:boolean`` => ``Mongoid::Boolean``
-- ``:date`` => ``Date``
-- ``:date_time`` => ``DateTime``
-- ``:float`` => ``Float``
-- ``:hash`` => ``Hash``
-- ``:integer`` => ``Integer``
-- ``:object_id`` => ``BSON::ObjectId``
-- ``:range`` => ``Range``
-- ``:regexp`` => ``Regexp``
-- ``:set`` => ``Set``
-- ``:string`` => ``String``
-- ``:stringified_symbol`` => ``StringifiedSymbol``
-- ``:symbol`` => ``Symbol``
-- ``:time`` => ``Time``
-
-
-.. _field-default-values:
-
-Specifying Field Default Values
--------------------------------
-
-A field can be configured to have a default value. The default value can be
-fixed, as in the following example:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
-
- field :state, type: String, default: 'created'
- end
-
-The default value can also be specified as a ``Proc``:
-
-.. code-block:: ruby
-
- class Order
- include Mongoid::Document
-
- field :fulfill_by, type: Time, default: ->{ Time.now + 3.days }
- end
-
-.. note::
-
- Default values that are not ``Proc`` instances are evaluated at class load
- time, meaning the following two definitions are not equivalent:
-
- .. code-block:: ruby
-
- field :submitted_at, type: Time, default: Time.now
- field :submitted_at, type: Time, default: ->{ Time.now }
-
- The second definition is most likely the desired one, which causes the
- time of submission to be set to the current time at the moment of
- document instantiation.
-
-To set a default which depends on the document's state, use ``self``
-inside the ``Proc`` instance which would evaluate to the document instance
-being operated on:
-
-.. code-block:: ruby
-
- field :fulfill_by, type: Time, default: ->{
- # Order should be fulfilled in 2 business hours.
- if (7..8).include?(self.submitted_at.hour)
- self.submitted_at + 4.hours
- elsif (9..3).include?(self.submitted_at.hour)
- self.submitted_at + 2.hours
- else
- (self.submitted_at + 1.day).change(hour: 11)
- end
- }
-
-When defining a default value as a ``Proc``, Mongoid will apply the default
-after all other attributes are set and associations are initialized.
-To have the default be applied before the other attributes are set,
-use the ``pre_processed: true`` field option:
-
-.. code-block:: ruby
-
- field :fulfill_by, type: Time, default: ->{ Time.now + 3.days },
- pre_processed: true
-
-The ``pre_processed: true`` option is also necessary when specifying a custom
-default value via a ``Proc`` for the ``_id`` field, to ensure the ``_id``
-is set correctly via associations:
-
-.. code-block:: ruby
-
- field :_id, type: String, default: -> { 'hello' }, pre_processed: true
-
-
-.. _storage-field-names:
-
-Specifying Storage Field Names
-------------------------------
-
-One of the drawbacks of having a schemaless database is that MongoDB must
-store all field information along with every document, meaning that it
-takes up a lot of storage space in RAM and on disk. A common pattern to limit
-this is to alias fields to a small number of characters, while keeping the
-domain in the application expressive. Mongoid allows you to do this and
-reference the fields in the domain via their long names in getters, setters,
-and criteria while performing the conversion for you.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :n, as: :name, type: String
- end
-
- band = Band.new(name: "Placebo")
- band.attributes # { "n" => "Placebo" }
-
- criteria = Band.where(name: "Placebo")
- criteria.selector # { "n" => "Placebo" }
-
-
-.. _field-aliases:
-
-Field Aliases
--------------
-
-It is possible to define field aliases. The value will be stored in the
-destination field but can be accessed from either the destination field or
-from the aliased field:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- alias_attribute :n, :name
- end
-
- band = Band.new(n: 'Astral Projection')
- # => #
-
- band.attributes
- # => {"_id"=>BSON::ObjectId('5fc1c1ee2c97a64accbeb5e1'), "name"=>"Astral Projection"}
-
- band.n
- # => "Astral Projection"
-
-Aliases can be removed from model classes using the ``unalias_attribute``
-method.
-
-.. code-block:: ruby
-
- class Band
- unalias_attribute :n
- end
-
-.. _unalias-id:
-
-Unaliasing ``id``
-`````````````````
-
-``unalias_attribute`` can be used to remove the predefined ``id`` alias.
-This is useful for storing different values in ``id`` and ``_id`` fields:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- unalias_attribute :id
- field :id, type: String
- end
-
- Band.new(id: '42')
- # => #
-
-
-Reserved Names
---------------
-
-Attempting to define a field on a document that conflicts with a reserved
-method name in Mongoid will raise an error. The list of reserved names can
-be obtained by invoking the ``Mongoid.destructive_fields`` method.
-
-
-Field Redefinition
-------------------
-
-By default Mongoid allows redefining fields on a model. To raise an error
-when a field is redefined, set the ``duplicate_fields_exception``
-:ref:`configuration option ` to ``true``.
-
-With the option set to true, the following example will raise an error:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :name
-
- field :name, type: String
- end
-
-To define the field anyway, use the ``overwrite: true`` option:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :name
-
- field :name, type: String, overwrite: true
- end
-
-
-.. _custom-id:
-
-Custom IDs
-----------
-
-By default, Mongoid defines the ``_id`` field on documents to contain a
-``BSON::ObjectId`` value which is automatically generated by Mongoid.
-
-It is possible to replace the ``_id`` field definition to change the type
-of the ``_id`` values or have different default values:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :_id, type: String, default: ->{ name }
- end
-
-It is possible to omit the default entirely:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :_id, type: String
- end
-
-If the default on ``_id`` is omitted, and no ``_id`` value is provided by
-your application, Mongoid will persist the document without the ``_id``
-value. In this case, if the document is a top-level document, an ``_id``
-value will be assigned by the server; if the document is an embedded document,
-no ``_id`` value will be assigned. Mongoid will not automatically retrieve
-this value, if assigned, when the document is persisted - you
-must obtain the persisted value (and the complete persisted document) using
-other means:
-
-.. code-block:: ruby
-
- band = Band.create!
- => #
- band.id
- => nil
- band.reload
- # raises Mongoid::Errors::DocumentNotFound
- Band.last
- => #
-
-Omitting ``_id`` fields is more common in :ref:`embedded documents `.
-
-Mongoid also defines the ``id`` field aliased to ``_id``. The ``id``
-alias can :ref:`be removed ` if desired (such as to integrate
-with systems that use the ``id`` field to store value different from ``_id``.
-
-.. _uncastable-values:
-
-Uncastable Values
------------------
-
-In Mongoid 8, Mongoid has standardized the treatment of the assignment and
-reading of "uncastable" values. A value is considered "uncastable" when it
-cannot be coerced to the type of its field. For example, an array would be an
-"uncastable" value to an Integer field.
-
-
-Assigning Uncastable Values
-```````````````````````````
-
-The assignment of uncastable values has been standardized to assign ``nil`` by
-default. Consider the following example:
-
-.. code::
-
- class User
- include Mongoid::Document
-
- field :name, type: Integer
- end
-
- User.new(name: [ "hello" ])
-
-Assigning an array to a field of type Integer doesn't work since an array can't
-be coerced to an Integer. The assignment of uncastable values to a field will
-cause a ``nil`` to be written:
-
-.. code::
-
- user = User.new(name: [ "Mike", "Trout" ])
- # => #
-
-Note that the original uncastable values will be stored in the
-``attributes_before_type_cast`` hash with their field names:
-
-.. code::
-
- user.attributes_before_type_cast["name"]
- # => ["Mike", "Trout"]
-
-.. note::
-
- Note that for numeric fields, any class that defines ``to_i`` for Integer
- fields, ``to_f`` for Floats, and ``to_d`` for BigDecimals, is castable.
- Strings are the exception and will only call the corresponding ``to_*``
- method if the string is numeric. If a class only defines ``to_i`` and not
- ``to_f`` and is being assigned to a Float field, this is uncastable, and Mongoid
- will not perform a two-step conversion (i.e. ``to_i`` and then ``to_f``).
-
-
-Reading Uncastable Values
-`````````````````````````
-
-When documents in the database contain values of different types than their
-representations in Mongoid, if Mongoid cannot coerce them into the correct type,
-it will replace the value with ``nil``. Consider the following model and document in the
-database:
-
-.. code::
-
- class User
- include Mongoid::Document
-
- field :name, type: Integer
- end
-
-.. code::
-
- { _id: ..., name: [ "Mike", "Trout" ] }
-
-Reading this document from the database will result in the model's name field
-containing ``nil``:
-
-.. code::
-
- User.first.name
- # => nil
-
-The database value of type array cannot be stored in the attribute, since the
-array can't be coerced to an Integer. Note that the original uncastable values
-will be stored in the ``attributes_before_type_cast`` hash with their field
-names:
-
-.. code::
-
- user.attributes_before_type_cast["name"]
- # => ["Mike", "Trout"]
-
-.. note::
-
- The ``demongoize`` methods on container objects (i.e. Hash, Array) have not
- been changed to permit automatic persistence of mutated container attributes.
- See `MONGOID-2951 `_ for a
- longer discussion of this topic.
-
-
-.. _customizing-field-behavior:
-
-Customizing Field Behavior
-==========================
-
-Mongoid offers several ways to customize the behavior of fields.
-
-
-.. _custom-getters-and-setters:
-
-Custom Getters And Setters
---------------------------
-
-You may override getters and setters for fields to modify the values
-when they are being accessed or written. The getters and setters use the
-same name as the field. Use ``read_attribute`` and ``write_attribute``
-methods inside the getters and setters to operate on the raw attribute
-values.
-
-For example, Mongoid provides the ``:default`` field option to write a
-default value into the field. If you wish to have a field default value
-in your application but do not wish to persist it, you can override the
-getter as follows:
-
-.. code-block:: ruby
-
- class DistanceMeasurement
- include Mongoid::Document
-
- field :value, type: Float
- field :unit, type: String
-
- def unit
- read_attribute(:unit) || "m"
- end
-
- def to_s
- "#{value} #{unit}"
- end
- end
-
- measurement = DistanceMeasurement.new(value: 2)
- measurement.to_s
- # => "2.0 m"
- measurement.attributes
- # => {"_id"=>BSON::ObjectId('613fa0b0a15d5d61502f3447'), "value"=>2.0}
-
-To give another example, a field which converts empty strings to nil values
-may be implemented as follows:
-
-.. code-block:: ruby
-
- class DistanceMeasurement
- include Mongoid::Document
-
- field :value, type: Float
- field :unit, type: String
-
- def unit=(value)
- if value.blank?
- value = nil
- end
- write_attribute(:unit, value)
- end
- end
-
- measurement = DistanceMeasurement.new(value: 2, unit: "")
- measurement.attributes
- # => {"_id"=>BSON::ObjectId('613fa15aa15d5d617216104c'), "value"=>2.0, "unit"=>nil}
-
-
-.. _custom-field-types:
-
-Custom Field Types
-------------------
-
-You can define custom types in Mongoid and determine how they are serialized
-and deserialized. In this example, we define a new field type ``Point``, which we
-can use in our model class as follows:
-
-.. code-block:: ruby
-
- class Profile
- include Mongoid::Document
- field :location, type: Point
- end
-
-Then make a Ruby class to represent the type. This class must define methods
-used for MongoDB serialization and deserialization as follows:
-
-.. code-block:: ruby
-
- class Point
-
- attr_reader :x, :y
-
- def initialize(x, y)
- @x, @y = x, y
- end
-
- # Converts an object of this instance into a database friendly value.
- # In this example, we store the values in the database as array.
- def mongoize
- [ x, y ]
- end
-
- class << self
-
- # Takes any possible object and converts it to how it would be
- # stored in the database.
- def mongoize(object)
- case object
- when Point then object.mongoize
- when Hash then Point.new(object[:x], object[:y]).mongoize
- else object
- end
- end
-
- # Get the object as it was stored in the database, and instantiate
- # this custom class from it.
- def demongoize(object)
- Point.new(object[0], object[1])
- end
-
- # Converts the object that was supplied to a criteria and converts it
- # into a query-friendly form.
- def evolve(object)
- case object
- when Point then object.mongoize
- else object
- end
- end
- end
- end
-
-The instance method ``mongoize`` takes an instance of your custom type object, and
-converts it into a representation of how it will be stored in the database, i.e. to pass
-to the MongoDB Ruby driver. In our example above, we want to store our ``Point``
-object as an ``Array`` in the form ``[ x, y ]``.
-
-The class method ``mongoize`` is similar to the instance method, however it must handle
-objects of all possible types as inputs. The ``mongoize`` method is used when calling the
-setter methods for fields of your custom type.
-
-.. code-block:: ruby
-
- point = Point.new(12, 24)
- venue = Venue.new(location: point) # This uses the Point#mongoize instance method.
- venue = Venue.new(location: [ 12, 24 ]) # This uses the Point.mongoize class method.
-
-The class method ``demongoize`` does the inverse of ``mongoize``. It takes the raw object
-from the MongoDB Ruby driver and converts it to an instance of your custom type.
-In this case, the database driver returns an ``Array`` and we instantiate a ``Point`` from it.
-The ``demongoize`` method is used when calling the getters of fields for your custom type.
-Note that in the example above, since ``demongoize`` calls ``Point.new``, a new instance of
-``Point`` will be generated on each call to the getter.
-
-Mongoid will always call the ``demongoize`` method on values that were
-retrieved from the database, but applications may, in theory, call
-``demongoize`` with arbitrary input. It is recommended that applications add
-handling for arbitrary input in their ``demongoize`` methods. We can rewrite
-``Point``'s demongoize method as follows:
-
-.. code:: ruby
-
- def demongoize(object)
- if object.is_a?(Array) && object.length == 2
- Point.new(object[0], object[1])
- end
- end
-
-Notice that ``demongoize`` will only create a new ``Point`` if given an array
-of length 2, and will return ``nil`` otherwise. Both the ``mongoize`` and
-``demongoize`` methods should be prepared to receive arbitrary input and should
-return ``nil`` on values that are uncastable to your custom type. See the
-section on :ref:`Uncastable Values ` for more details.
-
-Lastly, the class method ``evolve`` is similar to ``mongoize``, however it is used
-when transforming objects for use in Mongoid query criteria.
-
-.. code-block:: ruby
-
- point = Point.new(12, 24)
- Venue.where(location: point) # This uses Point.evolve
-
-The ``evolve`` method should also be prepared to receive arbitrary input,
-however, unlike the ``mongoize`` and ``demongoize`` methods, it should return
-the inputted value on values that are uncastable to your custom type. See the
-section on :ref:`Uncastable Values ` for more details.
-
-
-.. _phantom-custom-field-types:
-
-Phantom Custom Field Types
-``````````````````````````
-
-The custom field type may perform conversions from user-visible attribute
-values to the values stored in the database when the user-visible attribute
-value type is different from the declared field type. For example, this
-can be used to implement a mapping from one enumeration to another, to
-have more descriptive values in the application and more compact values stored
-in the database:
-
-.. code-block:: ruby
-
- class ColorMapping
-
- MAPPING = {
- 'black' => 0,
- 'white' => 1,
- }.freeze
-
- INVERSE_MAPPING = MAPPING.invert.freeze
-
- class << self
-
- # Takes application-scope value and converts it to how it would be
- # stored in the database. Converts invalid values to nil.
- def mongoize(object)
- MAPPING[object]
- end
-
- # Get the value as it was stored in the database, and convert to
- # application-scope value. Converts invalid values to nil.
- def demongoize(object)
- INVERSE_MAPPING[object]
- end
-
- # Converts the object that was supplied to a criteria and converts it
- # into a query-friendly form. Returns invalid values as is.
- def evolve(object)
- MAPPING.fetch(object, object)
- end
- end
- end
-
- class Profile
- include Mongoid::Document
- field :color, type: ColorMapping
- end
-
- profile = Profile.new(color: 'white')
- profile.color
- # => "white"
-
- # Writes 0 to color field
- profile.save!
-
-
-.. _custom-field-options:
-
-Custom Field Options
---------------------
-
-You may define custom options for the ``field`` macro function
-which extend its behavior at the your time model classes are loaded.
-
-As an example, we will define a ``:max_length`` option which will add a length
-validator for the field. First, declare the new field option in an initializer,
-specifying its handler function as a block:
-
-.. code-block:: ruby
-
- # in /config/initializers/mongoid_custom_fields.rb
-
- Mongoid::Fields.option :max_length do |model, field, value|
- model.validates_length_of field.name, maximum: value
- end
-
-Then, use it your model class:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :name, type: String, max_length: 10
- end
-
-Note that the handler function will be invoked whenever the option is used
-in the field definition, even if the option's value is false or nil.
-
-
-.. _dynamic-fields:
-
-Dynamic Fields
-==============
-
-By default, Mongoid requires all fields that may be set on a document to
-be explicitly defined using ``field`` declarations. Mongoid also supports
-creating fields on the fly from an arbitrary hash or documents stored in
-the database. When a model uses fields not explicitly defined, such fields
-are called *dynamic fields*.
-
-To enable dynamic fields, include ``Mongoid::Attributes::Dynamic`` module
-in the model:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- include Mongoid::Attributes::Dynamic
- end
-
- bob = Person.new(name: 'Bob', age: 42)
- bob.name
- # => "Bob"
-
-It is possible to use ``field`` declarations and dynamic fields in the same
-model class. Attributes for which there is a ``field`` declaration will be
-treated according to the ``field`` declaration, with remaining attributes
-being treated as dynamic fields.
-
-Attribute values in the dynamic fields must initially be set by either
-passing the attribute hash to the constructor, mass assignment via
-``attributes=``, mass assignment via ``[]=``, using ``write_attribute``,
-or they must already be present in the database.
-
-.. code-block:: ruby
-
- # OK
- bob = Person.new(name: 'Bob')
-
- # OK
- bob = Person.new
- bob.attributes = {age: 42}
-
- # OK
- bob = Person.new
- bob['age'] = 42
-
- # Raises NoMethodError: undefined method age=
- bob = Person.new
- bob.age = 42
-
- # OK
- bob = Person.new
- # OK - string access
- bob.write_attribute('age', 42)
- # OK - symbol access
- bob.write_attribute(:name, 'Bob')
-
- # OK, initializes attributes from whatever is in the database
- bob = Person.find('123')
-
-If an attribute is not present in a particular model instance's attributes
-hash, both the reader and the writer for the corresponding field are not
-defined, and invoking them raises ``NoMethodError``:
-
-.. code-block:: ruby
-
- bob = Person.new
- bob.attributes = {age: 42}
-
- bob.age
- # => 42
-
- # raises NoMethodError
- bob.name
-
- # raises NoMethodError
- bob.name = 'Bob'
-
- # OK
- bob['name'] = 'Bob'
-
- bob.name
- # => "Bob"
-
-Attributes can always be read using mass attribute access or ``read_attribute``
-(this applies to models not using dynamic fields as well):
-
-.. code-block:: ruby
-
- bob = Person.new(age: 42)
-
- # OK - string access
- bob['name']
- # => nil
-
- # OK - symbol access
- bob[:name]
- # => nil
-
- # OK - string access
- bob['age']
- # => 42
-
- # OK - symbol access
- bob[:age]
- # => 42
-
- # OK
- bob.attributes['name']
- # => nil
-
- # OK
- bob.attributes['age']
- # => 42
-
- # Returns nil - keys are always strings
- bob.attributes[:age]
- # => nil
-
- # OK
- bob.read_attribute('name')
- # => nil
-
- # OK
- bob.read_attribute(:name)
- # => nil
-
- # OK - string access
- bob.read_attribute('age')
- # => 42
-
- # OK - symbol access
- bob.read_attribute(:age)
- # => 42
-
-.. note::
-
- The values returned from the ``read_attribute`` method, and those stored in
- the ``attributes`` hash, are the ``mongoized`` values.
-
-
-Special Characters in Field Names
----------------------------------
-
-Mongoid permits dynamic field names to include spaces and punctuation:
-
-.. code-block:: ruby
-
- bob = Person.new('hello world' => 'MDB')
- bob.send('hello world')
- # => "MDB"
-
- bob.write_attribute("hello%world", 'MDB')
- bob[:"hello%world"]
- # => "MDB"
-
-
-.. _localized-fields:
-
-Localized Fields
-================
-
-Mongoid supports localized fields via the `I18n gem `_.
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
- field :description, type: String, localize: true
- end
-
-By telling the field to ``localize``, Mongoid will under the covers store the field
-as a hash of locale/value pairs, but normal access to it will behave like a string.
-
-.. code-block:: ruby
-
- I18n.default_locale = :en
- product = Product.new
- product.description = "Marvelous!"
- I18n.locale = :de
- product.description = "Fantastisch!"
-
- product.attributes
- # { "description" => { "en" => "Marvelous!", "de" => "Fantastisch!" }
-
-You can get and set all the translations at once by using the corresponding ``_translations`` method.
-
-.. code-block:: ruby
-
- product.description_translations
- # { "en" => "Marvelous!", "de" => "Fantastisch!" }
- product.description_translations =
- { "en" => "Marvelous!", "de" => "Wunderbar!" }
-
-Localized fields can be used with any field type. For example, they can be used
-with float fields for differences with currency:
-
-.. code:: ruby
-
- class Product
- include Mongoid::Document
-
- field :price, type: Float, localize: true
- field :currency, type: String, localize: true
- end
-
-By creating the model in this way, we can separate the price from the currency
-type, which allows you to use all of the number-related functionalities on the
-price when querying or aggregating that field (provided that you index into the
-stored translations hash). We can create an instance of this model as follows:
-
-.. code:: ruby
-
- product = Product.new
- I18n.locale = :en
- product.price = 1.00
- product.currency = "$"
- I18n.locale = :he
- product.price = 3.24
- product.currency = "₪"
-
- product.attributes
- # => { "price" => { "en" => 1.0, "he" => 3.24 }, "currency" => { "en" => "$", "he" => "₪" } }
-
-
-.. _present-fields:
-
-Localize ``:present`` Field Option
-----------------------------------
-
-Mongoid supports the ``:present`` option when creating a localized field:
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
- field :description, localize: :present
- end
-
-This option automatically removes ``blank`` values (i.e. those that return true
-for the ``blank?`` method) from the ``_translations`` hash:
-
-.. code-block:: ruby
-
- I18n.default_locale = :en
- product = Product.new
- product.description = "Marvelous!"
- I18n.locale = :de
- product.description = "Fantastisch!"
-
- product.description_translations
- # { "en" => "Marvelous!", "de" => "Fantastisch!" }
-
- product.description = ""
- product.description_translations
- # { "en" => "Marvelous!" }
-
-When the empty string is written for the ``:de`` locale, the ``"de"`` key is
-removed from the ``_translations`` hash instead of writing the empty string.
-
-
-Fallbacks
----------
-
-Mongoid integrates with
-`i18n fallbacks `_.
-To use the fallbacks, the respective functionality must be explicitly enabled.
-
-In a Rails application, set the ``config.i18n.fallbacks`` configuration setting
-to ``true`` in your environment and specify the fallback languages:
-
-.. code-block:: ruby
-
- config.i18n.fallbacks = true
- config.after_initialize do
- I18n.fallbacks[:de] = [ :en, :es ]
- end
-
-In a non-Rails application, include the fallbacks module into the I18n backend
-you are using and specify the fallback languages:
-
-.. code-block:: ruby
-
- require "i18n/backend/fallbacks"
- I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
- I18n.fallbacks[:de] = [ :en, :es ]
-
-When fallbacks are enabled, if a translation is not present in the active
-language, translations will be looked up in the fallback languages:
-
-.. code-block:: ruby
-
- product = Product.new
- I18n.locale = :en
- product.description = "Marvelous!"
- I18n.locale = :de
- product.description # "Marvelous!"
-
-Mongoid also defines a ``:fallbacks`` option on fields, which can be used to
-disable fallback functionality on a specific field:
-
-.. code:: ruby
-
- class Product
- include Mongoid::Document
- field :description, type: String, localize: true, fallbacks: false
- end
-
- product = Product.new
- I18n.locale = :en
- product.description = "Marvelous!"
- I18n.locale = :de
- product.description # nil
-
-Note that this option defaults to ``true``.
-
-.. note::
-
- In i18n 1.1, the behavior of fallbacks `changed `_
- to always require an explicit list of fallback locales rather than falling
- back to the default locale when no fallback locales have been provided.
-
-
-Querying
---------
-
-When querying for localized fields using Mongoid's criteria API, Mongoid will automatically
-alter the criteria to match the current locale.
-
-.. code-block:: ruby
-
- # Match all products with Marvelous as the description. Locale is en.
- Product.where(description: "Marvelous!")
- # The resulting MongoDB query filter: { "description.en" : "Marvelous!" }
-
-
-Indexing
---------
-
-If you plan to be querying extensively on localized fields, you should index each of the
-locales that you plan on searching on.
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
- field :description, localize: true
-
- index "description.de" => 1
- index "description.en" => 1
- end
-
-
-.. _read-only:
-
-Read-Only Attributes
-====================
-
-You can tell Mongoid that certain attributes are read-only. This will allow
-documents to be created with these attributes, but changes to them will be
-ignored when using mass update methods such as ``update_attributes``:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :origin, type: String
-
- attr_readonly :name, :origin
- end
-
- band = Band.create(name: "Placebo")
- band.update_attributes(name: "Tool") # Filters out the name change.
-
-If you explicitly try to update or remove a read-only attribute by itself,
-a ``ReadonlyAttribute`` exception will be raised:
-
-.. code-block:: ruby
-
- band.update_attribute(:name, "Tool") # Raises the error.
- band.remove_attribute(:name) # Raises the error.
-
-Assignments to read-only attributes using their setters will be ignored:
-
-.. code-block:: ruby
-
- b = Band.create!(name: "The Rolling Stones")
- # => #
- b.name = "The Smashing Pumpkins"
- # => "The Smashing Pumpkins"
- b.name
- # => "The Rolling Stones"
-
-Calls to atomic persistence operators, like ``bit`` and ``inc``, will persist
-changes to read-only fields.
-
-Timestamp Fields
-================
-
-Mongoid supplies a timestamping module in ``Mongoid::Timestamps`` which
-can be included to get basic behavior for ``created_at`` and
-``updated_at`` fields.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- include Mongoid::Timestamps
- end
-
-You may also choose to only have specific timestamps for creation or
-modification.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- include Mongoid::Timestamps::Created
- end
-
- class Post
- include Mongoid::Document
- include Mongoid::Timestamps::Updated
- end
-
-If you want to turn off timestamping for specific calls, use the timeless
-method:
-
-.. code-block:: ruby
-
- person.timeless.save
- Person.timeless.create!
-
-If you'd like shorter timestamp fields with aliases on them to save space,
-you can include the short versions of the modules.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- include Mongoid::Timestamps::Short # For c_at and u_at.
- end
-
- class Band
- include Mongoid::Document
- include Mongoid::Timestamps::Created::Short # For c_at only.
- end
-
- class Band
- include Mongoid::Document
- include Mongoid::Timestamps::Updated::Short # For u_at only.
- end
-
-
-.. _field-names-with-periods-and-dollar-signs:
-
-Field Names with Dots/Periods (``.``) and Dollar Signs (``$``)
-==============================================================
-
-Using dots/periods (``.``) in fields names and starting a field name with
-a dollar sign (``$``) is not recommended, as Mongoid provides limited support
-for retrieving and operating on the documents stored in those fields.
-
-Both Mongoid and MongoDB query language (MQL) generally use the dot/period
-character (``.``) to separate field names in a field path that traverses
-embedded documents, and words beginning with the dollar sign (``$``) as
-operators. MongoDB provides `limited support
-`_
-for using field names containing dots and starting with the dollar sign
-for interoperability with other software,
-however, due to this support being confined to specific operators
-(e.g. :manual:`getField `,
-:manual:`setField `) and
-requiring the usage of the aggregation pipeline for both queries and updates,
-applications should avoid using dots in field names and starting field names
-with the dollar sign if possible.
-
-Mongoid, starting in version 8, now allows users to access fields that begin with
-dollar signs and that contain dots/periods. They can be accessed using the ``send``
-method as follows:
-
-.. code::
-
- class User
- include Mongoid::Document
- field :"first.last", type: String
- field :"$_amount", type: Integer
- end
-
- user = User.first
- user.send(:"first.last")
- # => Mike.Trout
- user.send(:"$_amount")
- # => 42650000
-
-It is also possible to use ``read_attribute`` to access these fields:
-
-.. code::
-
- user.read_attribute("first.last")
- # => Mike.Trout
-
-Due to `server limitations `_,
-updating and replacing fields containing dots and dollars requires using special
-operators. For this reason, calling setters on these fields is prohibited and
-will raise an error:
-
-.. code::
-
- class User
- include Mongoid::Document
- field :"first.last", type: String
- field :"$_amount", type: Integer
- end
-
- user = User.new
- user.send(:"first.last=", "Shohei.Ohtani")
- # raises a InvalidDotDollarAssignment error
- user.send(:"$_amount=", 8500000)
- # raises a InvalidDotDollarAssignment error
-
diff --git a/docs/reference/indexes.txt b/docs/reference/indexes.txt
deleted file mode 100644
index 7a5d11a475..0000000000
--- a/docs/reference/indexes.txt
+++ /dev/null
@@ -1,278 +0,0 @@
-.. _indexes:
-
-****************
-Index Management
-****************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Specifying Indexes
-==================
-
-You can define indexes on documents using the index macro. Provide the key for
-the index along with a direction. Additional options can be supplied in the
-second options hash parameter:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :ssn
-
- index({ ssn: 1 }, { unique: true, name: "ssn_index" })
- end
-
-You can define indexes on embedded document fields as well:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- embeds_many :addresses
- index "addresses.street" => 1
- end
-
-You can index on multiple fields and provide direction:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :first_name
- field :last_name
-
- index({ first_name: 1, last_name: 1 }, { unique: true })
- end
-
-Indexes can be sparse:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :ssn
-
- index({ ssn: -1 }, { sparse: true })
- end
-
-For geospatial indexes, make sure the field being indexed is of type Array:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :location, type: Array
-
- index({ location: "2d" }, { min: -200, max: 200 })
- end
-
-Indexes can be scoped to a specific database:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :ssn
- index({ ssn: 1 }, { database: "users", unique: true, background: true })
- end
-
-You may use aliased field names in index definitions. Field aliases
-will also be resolved on the following options: ``partial_filter_expression``,
-``weights``, ``wildcard_projection``.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :a, as: :age
- index({ age: 1 }, { partial_filter_expression: { age: { '$gte' => 20 } })
- end
-
-.. note::
-
- The expansion of field name aliases in index options such as
- ``partial_filter_expression`` is performed according to the behavior of MongoDB
- server 6.0. Future server versions may change how they interpret these options,
- and Mongoid's functionality may not support such changes.
-
-Mongoid can define indexes on "foreign key" fields for associations.
-This only works on the association macro that the foreign key is stored on:
-
-.. code-block:: ruby
-
- class Comment
- include Mongoid::Document
- belongs_to :post, index: true
- has_and_belongs_to_many :preferences, index: true
- end
-
-*Deprecated:* In MongoDB 4.0 and earlier, users could control whether to build indexes
-in the foreground (blocking) or background (non-blocking, but less efficient) using the
-``background`` option.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- field :ssn
- index({ ssn: 1 }, { unique: true, background: true })
- end
-
-The default value of ``background`` is controlled by Mongoid's
-``background_indexing`` :ref:`configuration option `.
-
-The ``background`` option has `no effect as of MongoDB 4.2
-`_.
-
-
-Specifying Search Indexes on MongoDB Atlas
-==========================================
-
-If your application is connected to MongoDB Atlas, you can declare and manage
-search indexes on your models. (This feature is only available on MongoDB
-Atlas.)
-
-To declare a search index, use the ``search_index`` macro in your model:
-
-.. code-block:: ruby
-
- class Message
- include Mongoid::Document
-
- search_index { ... }
- search_index :named_index, { ... }
- end
-
-Search indexes may be given an explicit name; this is necessary if you have
-more than one search index on a model.
-
-
-Index Management Rake Tasks
-===========================
-
-When you want to create the indexes in the database, use the provided
-``db:mongoid:create_indexes`` Rake task:
-
-.. code-block:: bash
-
- $ rake db:mongoid:create_indexes
-
-Mongoid also provides a Rake task to delete all secondary indexes.
-
-.. code-block:: bash
-
- $ rake db:mongoid:remove_indexes
-
-Note: the output of these Rake tasks goes to the default logger configured
-by Rails. This is usually a file like ``log/development.log`` and not standard
-output.
-
-These create/remove indexes commands also works for just one model by running
-in Rails console:
-
-.. code-block:: ruby
-
- # Create indexes for Model
- Model.create_indexes
-
- # Remove indexes for Model
- Model.remove_indexes
-
-Managing Search Indexes on MongoDB Atlas
-----------------------------------------
-
-If you have defined search indexes on your model, there are rake tasks available
-for creating and removing those search indexes:
-
-.. code-block:: bash
-
- $ rake db:mongoid:create_search_indexes
- $ rake db:mongoid:remove_search_indexes
-
-By default, creating search indexes will wait for the indexes to be created,
-which can take quite some time. If you want to simply let the database create
-the indexes in the background, you can set the ``WAIT_FOR_SEARCH_INDEXES``
-environment variable to 0, like this:
-
-.. code-block:: bash
-
- $ rake WAIT_FOR_SEARCH_INDEXES=0 db:mongoid:create_search_indexes
-
-Note that the task for removing search indexes will remove all search indexes
-from all models, and should be used with caution.
-
-You can also add and remove search indexes for a single model by invoking the
-following in a Rails console:
-
-.. code-block:: ruby
-
- # Create all defined search indexes on the model; this will return
- # immediately and the indexes will be created in the background.
- Model.create_search_indexes
-
- # Remove all search indexes from the model
- Model.remove_search_indexes
-
- # Enumerate all search indexes on the model
- Model.search_indexes.each { |index| ... }
-
-
-Telling Mongoid Where to Look For Models
-----------------------------------------
-
-For non-Rails applications, Mongoid's rake tasks will look for models in
-``./app/models`` and ``./lib/models``. For Rails, Mongoid will look in
-``./app/models`` (or wherever you've configured Rails to look for models). If
-your models are in another location, you will need to tell Mongoid where to
-look for them with ``Mongoid.model_paths=``. You can do this by setting it
-in your application's Rakefile:
-
-.. code-block:: ruby
-
- # Rakefile
-
- # keep the defaults, but add more paths to look for models
- Mongoid.model_paths += [ "./src/models", "./lib/documents" ]
-
- # or, override the defaults entirely
- Mongoid.model_paths = [ "./src/models", "./lib/documents" ]
-
-Make sure that these paths are in your application's load path, as well. For
-example:
-
-.. code-block:: ruby
-
- # Rakefile
-
- $LOAD_PATHS.concat [ "./src/models", "./lib/documents" ]
-
-
-Using Rake Tasks With Non-Rails Applications
---------------------------------------------
-
-Mongoid's Rake tasks are automatically loaded in Rails applications using
-Mongoid. When using Mongoid with a non-Rails application, these tasks must
-be loaded manually:
-
-.. code-block:: ruby
-
- # Rakefile
-
- require 'mongoid'
- load 'mongoid/tasks/database.rake'
-
-If your application uses Bundler, you can require ``bundler/setup`` instead of
-explicitly requiring ``mongoid``:
-
-.. code-block:: ruby
-
- # Rakefile
-
- require 'bundler/setup'
- load 'mongoid/tasks/database.rake'
diff --git a/docs/reference/inheritance.txt b/docs/reference/inheritance.txt
deleted file mode 100644
index dcba02a96b..0000000000
--- a/docs/reference/inheritance.txt
+++ /dev/null
@@ -1,308 +0,0 @@
-.. _inheritance:
-
-***********
-Inheritance
-***********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-.. _inheritance-overview:
-
-Overview
-========
-
-Mongoid supports inheritance in both top level and embedded documents. When
-a child document inherits from a parent document, the parent document's
-fields, associations, validations and scopes are copied to the child document.
-
-.. code-block:: ruby
-
- class Canvas
- include Mongoid::Document
- field :name, type: String
- embeds_many :shapes
- end
-
- class Browser < Canvas
- field :version, type: Integer
- scope :recent, ->{ where(:version.gt => 3) }
- end
-
- class Firefox < Browser
- end
-
- class Shape
- include Mongoid::Document
- field :x, type: Integer
- field :y, type: Integer
- embedded_in :canvas
- end
-
- class Circle < Shape
- field :radius, type: Float
- end
-
- class Rectangle < Shape
- field :width, type: Float
- field :height, type: Float
- end
-
-In the above example, ``Canvas``, ``Browser`` and ``Firefox`` will all save in the canvases
-collection. An additional attribute ``_type`` is stored in order to make sure when loaded
-from the database the correct document is returned. This also holds true for the embedded
-documents ``Circle``, ``Rectangle``, and ``Shape``.
-
-.. note::
-
- When searching for a ``Circle``, the query will only return documents in the shape collection
- where the ``_type`` (or whatever the discriminator key was set to) field has the value ``Circle`` (or
- whatever the discriminator value was set to), all other discriminator values will be considered an object
- of the Shape class.
-
- Similarly, when querying by parent classes (``Canvas`` in this example), any documents in the collection
- that do not have a discriminator value, or whose discriminator value does not map to either the parent
- or any of its descendants, will be returned as instances of the parent class.
-
-
-.. _discriminator-key:
-
-Changing the Discriminator Key
-==============================
-
-Mongoid supports changing the discriminator key from the default ``_type``. There are a few
-cases where one might want to do this:
-
-1. For optimization: The user might want to use a shorter key like ``_t``.
-
-2. When trying to work with an existing system: It's possible the user is working with an existing system or dataset that has predefined keys.
-
-
-There are two ways to change the discriminator key, on the class level and on the global level.
-To change the discriminator key on the class level the user can set it directly on the parent class using
-the ``discriminator_key=`` method.
-Take the above example:
-
-.. code-block:: ruby
-
- class Shape
- include Mongoid::Document
- field :x, type: Integer
- field :y, type: Integer
- embedded_in :canvas
-
- self.discriminator_key = "shape_type"
- end
-
- class Circle < Shape
- field :radius, type: Float
- end
-
- class Rectangle < Shape
- field :width, type: Float
- field :height, type: Float
- end
-
-Here a call to the ``discriminator_key=`` setter was added to the parent class. Now, on
-creation of a Rectangle or Circle, a ``shape_type`` field will be added.
-
-Note that the discriminator key can only be modified in the parent class, and an error
-will be raised if trying to set it on the child class.
-
-If the discriminator key is changed after the child class is created, a new field is
-added with the new discriminator key value, and the old field will remain unchanged.
-For example:
-
-.. code-block:: ruby
-
- class Shape
- include Mongoid::Document
- field :x, type: Integer
- field :y, type: Integer
- embedded_in :canvas
- end
-
- class Circle < Shape
- field :radius, type: Float
- end
-
- class Rectangle < Shape
- field :width, type: Float
- field :height, type: Float
- end
-
- Shape.discriminator_key = "shape_type"
-
-In this case, on creation of a Rectangle or Circle, there will be both a ``shape_type``
-and a ``_type`` field that both default to ``Rectangle`` or ``Circle`` respectively.
-
-
-The discriminator key can also be set on the global level. Meaning, all classes will
-use the globally set discriminator key instead of ``_type``. Take the above example:
-
-.. code-block:: ruby
-
- Mongoid.discriminator_key = "_the_type"
-
- class Shape
- include Mongoid::Document
- field :x, type: Integer
- field :y, type: Integer
- embedded_in :canvas
- end
-
- class Circle < Shape
- field :radius, type: Float
- end
-
- class Rectangle < Shape
- field :width, type: Float
- field :height, type: Float
- end
-
-After setting the global discriminator key, all classes will use ``_the_type`` as
-the discriminator key and will not contain a ``_type`` field.
-
-Note that when defining the discriminator key on the global level, it must be set before the
-child class is defined for the child class to use that global value.
-On the global level, however, if the user does not set the discriminator key before defining a child
-class, the discriminator field will use the default ``_type`` and not the new global setting in
-that child class.
-
-
-.. _discriminator-value:
-
-Changing the Discriminator Value
-================================
-
-Mongoid also supports changing the discriminator value from the default value, which is the class name.
-One can change the discriminator value by using the ``discriminator_value=`` method on that specific class.
-
-Take the above example:
-
-.. code-block:: ruby
-
- class Shape
- include Mongoid::Document
- field :x, type: Integer
- field :y, type: Integer
- embedded_in :canvas
- end
-
- class Circle < Shape
- field :radius, type: Float
-
- self.discriminator_value = "round thing"
- end
-
- class Rectangle < Shape
- field :width, type: Float
- field :height, type: Float
- end
-
-Here, a call to the ``discriminator_value=`` setter was added to ``Circle``.
-Now, on creation of a ``Circle``, the document will contain a field with the key ``_type`` (or whatever the ``discriminator_key`` was changed to)
-and the value "round thing."
-
-.. note::
-
- Because the discriminator value overrides are declared in child classes,
- the child classes potentially found by a query must be loaded prior to
- sending that query. In the above example, the ``Circle`` class definition
- must be loaded when querying on ``Shape`` if the returned documents could
- potentially be instances of ``Circle`` (since autoloading wouldn't resolve
- ``"round thing"`` to ``Circle``).
-
-
-Querying Subclasses
-===================
-
-Querying for subclasses is handled in the normal manner, and although the documents are
-all in the same collection, queries will only return documents of the correct type,
-similar to Single Table Inheritance in ActiveRecord.
-
-.. code-block:: ruby
-
- # Returns Canvas documents and subclasses
- Canvas.where(name: "Paper")
- # Returns only Firefox documents
- Firefox.where(name: "Window 1")
-
-
-Associations
-============
-
-You can add any type of subclass to a has one or has many association, through
-either normal setting or through the build and create methods on the association:
-
-.. code-block:: ruby
-
- firefox = Firefox.new
- # Builds a Shape object
- firefox.shapes.build({ x: 0, y: 0 })
- # Builds a Circle object
- firefox.shapes.build({ x: 0, y: 0 }, Circle)
- # Creates a Rectangle object
- firefox.shapes.create({ x: 0, y: 0 }, Rectangle)
-
- rect = Rectangle.new(width: 100, height: 200)
- firefox.shapes
-
-
-.. _inheritance-persistence-context:
-
-Persistence Contexts
-====================
-
-Mongoid allows the persistence context of a subclass to be changed from the
-persistence context of its parent. This means that, using the ``store_in``
-method, we can store the documents of the subclasses in different collections
-(as well as different databases, clients) than their parents:
-
-.. code:: ruby
-
- class Shape
- include Mongoid::Document
- store_in collection: :shapes
- end
-
- class Circle < Shape
- store_in collection: :circles
- end
-
- class Square < Shape
- store_in collection: :squares
- end
-
- Shape.create!
- Circle.create!
- Square.create!
-
-Setting the collection on the children causes the documents for those children
-to be stored in the set collection, instead of in the parent's collection:
-
-.. code:: javascript
-
- > db.shapes.find()
- { "_id" : ObjectId("62fe9a493282a43d6b725e10"), "_type" : "Shape" }
- > db.circles.find()
- { "_id" : ObjectId("62fe9a493282a43d6b725e11"), "_type" : "Circle" }
- > db.squares.find()
- { "_id" : ObjectId("62fe9a493282a43d6b725e12"), "_type" : "Square" }
-
-If the collection is set on some of the subclasses and not others, the subclasses
-with set collections will store documents in those collections, and the
-subclasses without set collections will be store documents in the parent's
-collection.
-
-.. note::
-
- Note that changing the collection that a subclass is stored in will cause
- documents of that subclass to no longer be found in the results of querying
- its parent class.
diff --git a/docs/reference/map-reduce.txt b/docs/reference/map-reduce.txt
deleted file mode 100644
index 2251ffa915..0000000000
--- a/docs/reference/map-reduce.txt
+++ /dev/null
@@ -1,139 +0,0 @@
-.. _map-reduce:
-
-**********
-Map/Reduce
-**********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Mongoid provides a DSL around MongoDB's map/reduce framework, for performing
-custom map/reduce jobs or simple aggregations.
-
-.. note::
-
- The map-reduce operation is deprecated.
- The :ref:`aggregation framework ` provides better
- performance and usability than map-reduce operations, and should be
- preferred for new development.
-
-Execution
----------
-
-You can tell Mongoid off the class or a criteria to perform a map/reduce
-by calling ``map_reduce`` and providing map and reduce javascript
-functions.
-
-.. code-block:: ruby
-
- map = %Q{
- function() {
- emit(this.name, { likes: this.likes });
- }
- }
-
- reduce = %Q{
- function(key, values) {
- var result = { likes: 0 };
- values.forEach(function(value) {
- result.likes += value.likes;
- });
- return result;
- }
- }
-
- Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)
-
-Just like criteria, map/reduce calls are lazily evaluated. So nothing will
-hit the database until you iterate over the results, or make a call on the
-wrapper that would need to force a database hit.
-
-.. code-block:: ruby
-
- Band.map_reduce(map, reduce).out(replace: "mr-results").each do |document|
- p document # { "_id" => "Tool", "value" => { "likes" => 200 }}
- end
-
-The only required thing you provide along with a map/reduce is where to
-output the results. If you do not provide this an error will be raised.
-Valid options to ``#out`` are:
-
-- ``inline: 1``: Don't store the output in a collection.
-- ``replace: "name"``: Store in a collection with the
- provided name, and overwrite any documents that exist in it.
-- ``merge: "name"``: Store in a collection with the
- provided name, and merge the results with the existing documents.
-- ``reduce: "name"``: Store in a collection with the
- provided name, and reduce all existing results in that collection.
-
-Raw Results
------------
-
-Results of Map/Reduce execution can be retrieved via the ``execute`` method
-or its aliases ``raw`` and ``results``:
-
-.. code-block:: ruby
-
- mr = Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)
-
- mr.execute
- # => {"results"=>[{"_id"=>"Tool", "value"=>{"likes"=>200.0}}],
- "timeMillis"=>14,
- "counts"=>{"input"=>4, "emit"=>4, "reduce"=>1, "output"=>1},
- "ok"=>1.0,
- "$clusterTime"=>{"clusterTime"=>#, "signature"=>{"hash"=>, "keyId"=>0}},
- "operationTime"=>#}
-
-
-Statistics
-----------
-
-MongoDB servers 4.2 and lower provide Map/Reduce execution statistics. As of
-MongoDB 4.4, Map/Reduce is implemented via the aggregation pipeline and
-statistics described in this section are not available.
-
-The following methods are provided on the ``MapReduce`` object:
-
-- ``counts``: Number of documents read, emitted, reduced and output through
- the pipeline.
-- ``input``, ``emitted``, ``reduced``, ``output``: individual count methods.
- Note that ``emitted`` and ``reduced`` methods are named differently from
- hash keys in ``counts``.
-- ``time``: The time, in milliseconds, that Map/Reduce pipeline took to execute.
-
-The following code illustrates retrieving the statistics:
-
-.. code-block:: ruby
-
- mr = Band.where(:likes.gt => 100).map_reduce(map, reduce).out(inline: 1)
-
- mr.counts
- # => {"input"=>4, "emit"=>4, "reduce"=>1, "output"=>1}
-
- mr.input
- # => 4
-
- mr.emitted
- # => 4
-
- mr.reduced
- # => 1
-
- mr.output
- # => 1
-
- mr.time
- # => 14
-
-.. note::
-
- Each statistics method invocation re-executes the Map/Reduce pipeline.
- The results of execution are not stored by Mongoid. Consider using the
- ``execute`` method to retrieve the raw results and obtaining the statistics
- from the raw results if multiple statistics are desired.
diff --git a/docs/reference/nested-attributes.txt b/docs/reference/nested-attributes.txt
deleted file mode 100644
index 5803206ec8..0000000000
--- a/docs/reference/nested-attributes.txt
+++ /dev/null
@@ -1,140 +0,0 @@
-.. _nested-attributes:
-
-*****************
-Nested Attributes
-*****************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Nested attributes provide a mechanism for updating documents and their
-associations in a single operation by nesting attributes in a single
-parameters hash. This is useful when wanting to edit multiple documents
-within a single web form.
-
-Behavior
-========
-
-Nested attributes can be enabled for any association, embedded or referenced.
-To enable this for an association, simply provide the association name to the
-``accepts_nested_attributes_for`` macro.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- embeds_many :albums
- belongs_to :producer
- accepts_nested_attributes_for :albums, :producer
- end
-
-Note that when you add nested attributes functionality to a referenced
-association, Mongoid will automatically enable autosave for that association.
-
-When an association gains nested attributes behavior, an additional method is
-added to the base model, which should be used to update the attributes with
-the new functionality. This method is the association name plus ``_attributes=``.
-You can use this method directly, or more commonly the name of the method can
-be an attribute in the updates for the base class, in which case
-Mongoid will call the appropriate setter under the covers.
-
-.. code-block:: ruby
-
- band = Band.first
- band.producer_attributes = { name: "Flood" }
- band.attributes = { producer_attributes: { name: "Flood" }}
-
-Note that this will work with any attribute based setter method in Mongoid,
-including ``update``, ``update_attributes`` and ``attributes=``, as well as
-``create`` (and all of their corresponding bang methods). For example, creating
-a new person with associated address records can be done in a single
-statement, like this:
-
-.. code-block:: ruby
-
- person = Person.create(
- name: 'John Schmidt',
- addresses_attributes: [
- { type: 'home', street: '1234 Street Ave.', city: 'Somewhere' },
- { type: 'work', street: 'Parkway Blvd.', city: 'Elsewehre' },
- ])
-
-
-Creating Records
-----------------
-
-You can create new nested records via nested attributes by omitting
-an ``_id`` field:
-
-.. code-block:: ruby
-
- person = Person.first
- person.update(addresses_attributes: [
- { type: 'prior', street: '221B Baker St', city: 'London' } ])
-
-This will append the new record to the existing set; existing records will
-not be changed.
-
-
-Updating Records
-----------------
-
-If you specify an ``_id`` field for any of the nested records, the attributes
-will be used to update the record with that id:
-
-.. code-block:: ruby
-
- person = Person.first
- address = person.addresses.first
- person.update(addresses_attributes: [
- { _id: address._id, city: 'Lisbon' } ])
-
-Note that if there is no record with that id, a ``Mongoid::Errors::DocumentNotFound``
-exception will be raised.
-
-
-Destroying Records
-------------------
-
-You can also destroy records this way, by specifying a special
-``_destroy`` attribute. In order to use this, you must have passed
-``allow_destroy: true`` with the ``accepts_nested_attributes_for``
-declaration:
-
-.. code-block:: ruby
-
- class Person
- # ...
-
- accepts_nested_attributes_for :addresses, allow_destroy: true
- end
-
- person = Person.first
- address = person.addresses.first
- person.update(addresses_attributes: [
- { _id: address._id, _destroy: true } ])
-
-Note that, as with updates, if there is no record with that id,
-a ``Mongoid::Errors::DocumentNotFound`` exception will be raised.
-
-
-Combining Operations
---------------------
-
-Nested attributes allow you to combine all of these operations in
-a single statement! Here's an example that creates an address,
-updates another address, and destroys yet another address, all in
-a single command:
-
-.. code-block:: ruby
-
- person = Person.first
- person.update(addresses_attributes: [
- { type: 'alt', street: '1234 Somewhere St.', city: 'Cititon' },
- { _id: an_address_id, city: 'Changed City' },
- { _id: another_id, _destroy: true } ])
diff --git a/docs/reference/persistence-configuration.txt b/docs/reference/persistence-configuration.txt
deleted file mode 100644
index 6712fb5519..0000000000
--- a/docs/reference/persistence-configuration.txt
+++ /dev/null
@@ -1,268 +0,0 @@
-.. _persistence:
-
-*************************
-Persistence Configuration
-*************************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Document Storage
-================
-
-Mongoid by default stores documents in a collection that is the pluralized form of the class name.
-For the following ``Person`` class, the collection the document would get stored in would be named ``people``.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- end
-
-Model class names cannot end with "s", because it will be considered as the pluralized form of
-the word. For example "Status" would be considered as the plural form of "Statu",
-which will cause a few known problems.
-
-This is a limitation of the ``ActiveSupport::Inflector#classify`` which Mongoid uses to convert
-from filenames and collection names to class names. You can overcome this by specifying a custom
-inflection rule for your model class. For example, the following code will take care of the model
-named ``Status``.
-
-.. code-block:: ruby
-
- ActiveSupport::Inflector.inflections do |inflect|
- inflect.singular("status", "status")
- end
-
-The collection for the model's documents can be changed at the class level if you would like
-them persisted elsewhere. You can also change the database and client the model gets persisted
-in from the defaults.
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- store_in collection: "citizens", database: "other", client: "analytics"
- end
-
-The ``store_in`` macro can also take lambdas - a common case for this is multi-tenant applications.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- store_in database: ->{ Thread.current[:database] }
- end
-
-When a document is stored in the database the ruby object will get serialized into BSON
-and have a structure like so:
-
-.. code-block:: ruby
-
- {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e9"),
- "title" : "Sir",
- "name" : {
- "_id" : ObjectId("4d3ed089fb60ab534684b7ff"),
- "first_name" : "Durran"
- },
- "addresses" : [
- {
- "_id" : ObjectId("4d3ed089fb60ab534684b7e0"),
- "city" : "Berlin",
- "country" : "Deutschland"
- }
- ]
- }
-
-
-Persistence Context Attributes
-==============================
-
-Mongoid provides ``client_name``, ``database_name`` and ``collection_name``
-methods on model classes to determine the client, database and collection names
-used for persistence:
-
-.. code-block:: ruby
-
- Band.client_name
- # => :default
-
- Band.database_name
- # => "mongoid"
-
- Band.collection_name
- # => :bands
-
-
-Custom
-======
-
-There may be cases where you want to persist documents to different sources from their
-defaults, or with different options from the default. Mongoid provides run-time support
-for this as well as support on a per-model basis.
-
-
-Model-Level Persistence Options
--------------------------------
-
-On a per-model basis, you can tell it to store in a custom collection name, a different
-database, or a different client. The following example would store the Band class by
-default into a collection named "artists" in the database named "music", with the client "analytics".
-
-Note that the value supplied to the ``client`` option must be configured under ``clients``
-in your mongoid.yml.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- store_in collection: "artists", database: "music", client: "analytics"
- end
-
-If no ``store_in`` macro would have been provided, Mongoid would store the model in a
-collection named "bands" in the default database in the default client.
-
-
-Runtime Persistence Options
----------------------------
-
-It is possible to change the client, database and collection, as well as
-any of the MongoDB client options, used for persistence for a group of
-operations by using the ``with`` method on a model class or instance:
-
-.. code-block:: ruby
-
- Band.with(database: "music-non-stop") do |klass|
- klass.create(...)
-
- band = Band.first
-
- Band.create(...)
- end
-
- Band.with(collection: "artists") do |klass|
- klass.delete_all
-
- Band.delete_all
- end
-
- band.with(client: :tertiary) do |band_object|
- band_object.save!
-
- band.save!
- end
-
-The ``with`` method creates a temporary persistence context and a MongoDB
-client to be used for operations in the context. For the duration of the block,
-the persistence context on the model class or instance that ``with`` was
-called on is changed to the temporary persistence context. For convenience,
-the model class or instance that ``with`` was called on is yielded to the
-block.
-
-The temporary persistence context applies to both queries and writes.
-
-Care should be taken when performing persistence operations across different
-persistence contexts. For example, if a document is saved in a temporary
-persistence context, it may not exist in the default persistence context,
-failing subsequent updates:
-
-.. code-block:: ruby
-
- band = Band.new(name: "Scuba")
- band.with(collection: "artists") do |band_object|
- band_object.save!
- end
-
- # This will not save - updates the collection "bands" which does not have
- # the Scuba band
- band.update_attribute(likes: 1000)
-
- # This will update the document.
- band.with(collection: "artists") do |band_object|
- band_object.update_attribute(likes: 1000)
- end
-
-As of Mongoid 6.0, the ``with`` method must always be called with a block,
-and the temporary persistence context exists only for the duration of the block.
-This is because a new client is created under the covers with the options
-passed to ``with``. To ensure that this client is closed and its associated
-resources are freed, the scope when this client could be used must be
-well-defined.
-
-
-Global Override
-```````````````
-
-If you want to switch the persistence context for all operations at runtime, but don't want
-to be using with all over your code, Mongoid provides the ability to do this as the client
-and database level globally. The methods for this are ``Mongoid.override_client`` and
-``Mongoid.override_database``. A useful case for this are internationalized applications
-that store information for different locales in different databases or clients, but the
-schema in each remains the same.
-
-.. code-block:: ruby
-
- class BandsController < ApplicationController
- before_action :switch_database
- after_action :reset_database
-
- private
-
- def switch_database
- I18n.locale = params[:locale] || I18n.default_locale
- Mongoid.override_database("my_db_name_#{I18n.locale}")
- end
-
- def reset_database
- Mongoid.override_database(nil)
- end
- end
-
-In the above example, all persistence operations would be stored in the alternative
-database for all remaining operations on this thread. This is why the after request
-set the override back to nil - it ensures subsequent requests with no local params
-use the default option.
-
-Persistence context applies to both read and write operations. For example,
-secondary reads can be performed as follows:
-
-.. code-block:: ruby
-
- Band.with(read: {mode: :secondary}) do
- Band.count
- end
-
-
-Client and Collection Access
-----------------------------
-
-If you want to drop down to the driver level to perform operations, you can grab
-the Mongo client or collection from the model or document instance:
-
-.. code-block:: ruby
-
- Band.mongo_client
- band.mongo_client
- Band.collection
- band.collection
-
-From here you also have the same runtime persistence options using the client's ``#with``:
-
-.. code-block:: ruby
-
- client = Band.mongo_client.with(write: { w: 0 }, database: "musik")
- client[:artists].find(...)
-
-You can also override the :read or :write options on the collection using the collections ``#with``:
-
-.. code-block:: ruby
-
- collection_w_0 = Band.collection.with(write: { w: 0 })
- collection_w_0[:artists].find(...)
diff --git a/docs/reference/queries.txt b/docs/reference/queries.txt
deleted file mode 100644
index 0ef52259e7..0000000000
--- a/docs/reference/queries.txt
+++ /dev/null
@@ -1,2480 +0,0 @@
-.. _queries:
-
-*******
-Queries
-*******
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Mongoid provides a rich query DSL inspired by ActiveRecord. A trivial query
-looks as follows:
-
-.. code-block:: ruby
-
- Band.where(name: "Depeche Mode")
-
-A more complex query utilizing various Mongoid features could be as follows:
-
-.. code-block:: ruby
-
- Band.
- where(:founded.gte => "1980-01-01").
- in(name: [ "Tool", "Deftones" ]).
- union.
- in(name: [ "Melvins" ])
-
-The query methods return ``Mongoid::Criteria`` objects, which are chainable
-and lazily evaluated wrappers for MongoDB query language (MQL).
-The queries are executed when their result sets are iterated. For example:
-
-.. code-block:: ruby
-
- # Construct a Criteria object:
-
- Band.where(name: 'Deftones')
- # => #"Deftones"}
- # options: {}
- # class: Band
- # embedded: false>
-
- # Evaluate the query and get matching documents:
-
- Band.where(name: 'Deftones').to_a
- # => [#]
-
-Methods like ``first`` and ``last`` return the individual documents immediately.
-Otherwise, iterating a Criteria object with methods like ``each`` or ``map``
-retrieves the documents from the server. ``to_a`` can be used to force
-execution of a query that returns an array of documents, literally converting
-a Criteria object to an Array.
-
-When a query method is called on a Criteria instance, the method returns a new
-Criteria instance with the new conditions added to the existing conditions:
-
-.. code-block:: ruby
-
- scope = Band.where(:founded.gte => "1980-01-01")
- # => #{"$gte"=>"1980-01-01"}}
- # options: {}
- # class: Band
- # embedded: false>
-
- scope.where(:founded.lte => "2020-01-01")
- # => #{"$gte"=>"1980-01-01", "$lte"=>"2020-01-01"}}
- # options: {}
- # class: Band
- # embedded: false>
-
- scope
- # => #{"$gte"=>"1980-01-01"}}
- # options: {}
- # class: Band
- # embedded: false>
-
-
-Condition Syntax
-================
-
-Mongoid supports three ways of specifying individual conditions:
-
-1. Field syntax.
-2. MQL syntax.
-3. Symbol operator syntax.
-
-All syntaxes support querying embedded documents using the dot notation.
-All syntaxes respect field types, if the field being queried is defined in the
-model class, and field aliases.
-
-The examples in this section use the following model definition:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :founded, type: Integer
- field :m, as: :member_count, type: Integer
-
- embeds_one :manager
- end
-
- class Manager
- include Mongoid::Document
-
- embedded_in :band
-
- field :name, type: String
- end
-
-Field Syntax
-------------
-
-The simplest querying syntax utilizes the basic Ruby hashes. Keys can be
-symbols or strings, and correspond to field names in MongoDB documents:
-
-.. code-block:: ruby
-
- Band.where(name: "Depeche Mode")
- # => #"Depeche Mode"}
- # options: {}
- # class: Band
- # embedded: false>
-
- # Equivalent to:
-
- Band.where("name" => "Depeche Mode")
-
-MQL Syntax
-----------
-
-An MQL operator may be specified on any field using the hash syntax:
-
-.. code-block:: ruby
-
- Band.where(founded: {'$gt' => 1980})
- # => #{"$gt"=>1980}}
- # options: {}
- # class: Band
- # embedded: false>
-
- # Equivalent to:
-
- Band.where('founded' => {'$gt' => 1980})
-
-Symbol Operator Syntax
-----------------------
-
-MQL operators may be specified as methods on symbols for the respective field
-name, as follows:
-
-.. code-block:: ruby
-
- Band.where(:founded.gt => 1980)
- # => #{"$gt"=>1980}}
- # options: {}
- # class: Band
- # embedded: false>
-
-
-Fields
-======
-
-Querying on Defined Fields
---------------------------
-
-In order to query on a field, it is not necessary to add the field to
-:ref:`the model class definition `. However, if a field is defined in
-the model class, Mongoid will coerce query values to match defined field types
-when constructing the query:
-
-.. code-block:: ruby
-
- Band.where(name: 2020, founded: "2020")
- # => #"2020", "founded"=>2020}
- # options: {}
- # class: Band
- # embedded: false>
-
-Querying for Raw Values
------------------------
-
-If you'd like to bypass Mongoid's query type coercion behavior and query
-directly for the raw-typed value in the database, wrap the query value in
-``Mongoid::RawValue`` class. This can be useful when working with legacy data.
-
-.. code-block:: ruby
-
- Band.where(founded: Mongoid::RawValue("2020"))
- # => #"2020"}
- # options: {}
- # class: Band
- # embedded: false>
-
-Field Aliases
--------------
-
-Queries take into account :ref:`storage field names `
-and :ref:`field aliases `:
-
-.. code-block:: ruby
-
- Band.where(name: 'Astral Projection')
- # => #"Astral Projection"}
- # options: {}
- # class: Band
- # embedded: false>
-
-Since ``id`` and ``_id`` fields are aliases, either one can be used for queries:
-
-.. code-block:: ruby
-
- Band.where(id: '5ebdeddfe1b83265a376a760')
- # => #BSON::ObjectId('5ebdeddfe1b83265a376a760')}
- # options: {}
- # class: Band
- # embedded: false>
-
-
-Embedded Documents
-==================
-
-To match values of fields of embedded documents, use the dot notation:
-
-.. code-block:: ruby
-
- Band.where('manager.name' => 'Smith')
- # => #"Smith"}
- # options: {}
- # class: Band
- # embedded: false>
-
- Band.where(:'manager.name'.ne => 'Smith')
- # => #{"$ne"=>"Smith"}}
- # options: {}
- # class: Band
- # embedded: false>
-
-.. note::
-
- Queries always return top-level model instances, even if all of the
- conditions are referencing embedded documents.
-
-
-.. _logical-operations:
-
-Logical Operations
-==================
-
-Mongoid supports ``and``, ``or``, ``nor`` and ``not`` logical operations on
-``Criteria`` objects. These methods take one or more hash of conditions
-or another ``Criteria`` object as their arguments, with ``not`` additionally
-having an argument-free version.
-
-.. code-block:: ruby
-
- # and with conditions
- Band.where(label: 'Trust in Trance').and(name: 'Astral Projection')
-
- # or with scope
- Band.where(label: 'Trust in Trance').or(Band.where(name: 'Astral Projection'))
-
- # not with conditions
- Band.not(label: 'Trust in Trance', name: 'Astral Projection')
-
- # argument-less not
- Band.not.where(label: 'Trust in Trance', name: 'Astral Projection')
-
-For backwards compatibility with earlier Mongoid versions, all of the logical
-operation methods also accept arrays of parameters, which will be flattened
-to obtain the criteria. Passing arrays to logical operations is deprecated and
-may be removed in a future version of Mongoid.
-
-The following calls all produce the same query conditions:
-
-.. code-block:: ruby
-
- # Condition hashes passed to separate and invocations
- Band.and(name: 'SUN Project').and(member_count: 2)
-
- # Multiple condition hashes in the same and invocation
- Band.and({name: 'SUN Project'}, {member_count: 2})
-
- # Multiple condition hashes in an array - deprecated
- Band.and([{name: 'SUN Project'}, {member_count: 2}])
-
- # Condition hash in where and a scope
- Band.where(name: 'SUN Project').and(Band.where(member_count: 2))
-
- # Condition hash in and and a scope
- Band.and({name: 'SUN Project'}, Band.where(member_count: 2))
-
- # Scope as an array element, nested arrays - deprecated
- Band.and([Band.where(name: 'SUN Project'), [{member_count: 2}]])
-
- # All produce:
- # => #"SUN Project", "member_count"=>2}
- # options: {}
- # class: Band
- # embedded: false>
-
-
-Operator Combinations
----------------------
-
-As of Mongoid 7.1, logical operators (``and``, ``or``, ``nor`` and ``not``)
-have been changed to have the the same semantics as `those of ActiveRecord
-`_.
-To obtain the semantics of ``or`` as it behaved in Mongoid 7.0 and earlier,
-use ``any_of`` which is described below.
-
-When conditions are specified on the same field multiple times, all
-conditions are added to the criteria:
-
-.. code-block:: ruby
-
- Band.where(name: 1).where(name: 2).selector
- # => {"name"=>"1", "$and"=>[{"name"=>"2"}]}
-
- Band.where(name: 1).or(name: 2).selector
- # => {"$or"=>[{"name"=>"1"}, {"name"=>"2"}]}
-
-``any_of``, ``none_of``, ``nor`` and ``not`` behave similarly, with ``not`` producing
-different query shapes as described below.
-
-When ``and``, ``or`` and ``nor`` logical operators are used, they
-operate on the criteria built up to that point and its argument.
-``where`` has the same meaning as ``and``:
-
-.. code-block:: ruby
-
- # or joins the two conditions
- Band.where(name: 'Sun').or(label: 'Trust').selector
- # => {"$or"=>[{"name"=>"Sun"}, {"label"=>"Trust"}]}
-
- # or applies only to the first condition, the second condition is added
- # to the top level as $and
- Band.or(name: 'Sun').where(label: 'Trust').selector
- # => {"$or"=>[{"name"=>"Sun"}], "label"=>"Trust"}
-
- # Same as previous example - where and and are aliases
- Band.or(name: 'Sun').and(label: 'Trust').selector
- # => {"$or"=>[{"name"=>"Sun"}], "label"=>"Trust"}
-
- # Same operator can be stacked any number of times
- Band.or(name: 'Sun').or(label: 'Trust').selector
- # => {"$or"=>[{"name"=>"Sun"}, {"label"=>"Trust"}]}
-
- # The label: Foo condition is added to the top level as $and
- Band.where(name: 'Sun').or(label: 'Trust').where(label: 'Foo').selector
- # => {"$or"=>[{"name"=>"Sun"}, {"label"=>"Trust"}], "label"=>"Foo"}
-
-
-``and`` Behavior
-----------------
-
-The ``and`` method will add new simple conditions to the top level of the
-criteria, unless the receiving criteria already has a condition on the
-respective fields, in which case the conditions will be combined with ``$and``.
-
-.. code-block:: ruby
-
- Band.where(label: 'Trust in Trance').and(name: 'Astral Projection').selector
- # => {"label"=>"Trust in Trance Records", "name"=>"Astral Projection"}
-
- Band.where(name: /Best/).and(name: 'Astral Projection').selector
- # => {"name"=>/Best/, "$and"=>[{"name"=>"Astral Projection"}]}
-
-As of Mongoid 7.1, specifying multiple criteria on the same field with ``and``
-combines all criteria so specified, whereas in previous versions of Mongoid
-conditions on a field sometimes replaced previously specified conditions on
-the same field, depending on which form of ``and`` was used.
-
-
-``or``/``nor`` Behavior
-_----------------------
-
-``or`` and ``nor`` produce ``$or`` and ``$nor`` MongoDB operators, respectively,
-using the receiver and all of the arguments as operands. For example:
-
-.. code-block:: ruby
-
- Band.where(name: /Best/).or(name: 'Astral Projection')
- # => {"$or"=>[{"name"=>/Best/}, {"name"=>"Astral Projection"}]}
-
- Band.where(name: /Best/).and(name: 'Astral Projection').
- or(Band.where(label: /Records/)).and(label: 'Trust').selector
- # => {"$or"=>[{"name"=>/Best/, "$and"=>[{"name"=>"Astral Projection"}]}, {"label"=>/Records/}], "label"=>"Trust"}
-
-If the only condition on the receiver is another ``or``/``nor``, the new
-conditions are added to the existing list:
-
-.. code-block:: ruby
-
- Band.where(name: /Best/).or(name: 'Astral Projection').
- or(Band.where(label: /Records/)).selector
- # => {"$or"=>[{"name"=>/Best/}, {"name"=>"Astral Projection"}, {"label"=>/Records/}]}
-
-Use ``any_of`` to add a disjunction to a Criteria object while maintaining
-all of the conditions built up so far as they are.
-
-
-.. _any-of:
-
-``any_of`` Behavior
--------------------
-
-``any_of`` adds a disjunction built from its arguments to the existing
-conditions in the criteria. For example:
-
-.. code-block:: ruby
-
- Band.where(label: /Trust/).any_of({name: 'Astral Projection'}, {name: /Best/})
- # => {"label"=>/Trust/, "$or"=>[{"name"=>"Astral Projection"}, {"name"=>/Best/}]}
-
-The conditions are hoisted to the top level if possible:
-
-.. code-block:: ruby
-
- Band.where(label: /Trust/).any_of({name: 'Astral Projection'})
- # => {"label"=>/Trust/, "name"=>"Astral Projection"}
-
-
-.. _none-of:
-
-``none_of`` Behavior
---------------------
-
-``none_of`` adds a negated disjunction ("nor") built from its arguments to
-the existing conditions in the criteria. For example:
-
-.. code-block:: ruby
-
- Band.where(label: /Trust/).none_of({name: 'Astral Projection'}, {name: /Best/})
- # => {"label"=>/Trust/, "$nor"=>[{"name"=>"Astral Projection"}, {"name"=>/Best/}]}
-
-
-``not`` Behavior
-----------------
-
-``not`` method can be called without arguments, in which case it will negate
-the next condition that is specified. ``not`` can also be called with one
-or more hash conditions or ``Criteria`` objects, which will all be negated and
-added to the criteria.
-
-.. code-block:: ruby
-
- # not negates subsequent where
- Band.not.where(name: 'Best').selector
- # => {"name"=>{"$ne"=>"Best"}}
-
- # The second where is added as $and
- Band.not.where(name: 'Best').where(label: /Records/).selector
- # => {"name"=>{"$ne"=>"Best"}, "label"=>/Records/}
-
- # not negates its argument
- Band.not(name: 'Best').selector
- # => {"name"=>{"$ne"=>"Best"}}
-
-.. note::
-
- ``$not`` in MongoDB server cannot be used with a string argument.
- Mongoid uses ``$ne`` operator to achieve such a negation:
-
- .. code-block:: ruby
-
- # String negation - uses $ne
- Band.not.where(name: 'Best').selector
- # => {"name"=>{"$ne"=>"Best"}}
-
- # Regexp negation - uses $not
- Band.not.where(name: /Best/).selector
- # => {"name"=>{"$not"=>/Best/}}
-
-Similarly to ``and``, ``not`` will negate individual conditions for simple
-field criteria. For complex conditions and when a field already has a condition
-defined on it, since MongoDB server only supports the ``$not`` operator on
-a per-field basis rather than globally, Mongoid emulates ``$not`` by using
-an ``{'$and' => [{'$nor' => ...}]}`` construct:
-
-.. code-block:: ruby
-
- # Simple condition
- Band.not(name: /Best/).selector
- # => {"name"=>{"$not"=>/Best/}}
-
- # Complex conditions
- Band.where(name: /Best/).not(name: 'Astral Projection').selector
- # => {"name"=>/Best/, "$and"=>[{"$nor"=>[{"name"=>"Astral Projection"}]}]}
-
- # Symbol operator syntax
- Band.not(:name.ne => 'Astral Projection')
- # => #[{"$nor"=>[{"name"=>{"$ne"=>"Astral Projection"}}]}]}
- # options: {}
- # class: Band
- # embedded: false>
-
-If using ``not`` with arrays or regular expressions, please note the
-caveats/limitations of ``$not`` `stated in the MongoDB server documentation
-`_.
-
-
-Incremental Query Construction
-==============================
-
-By default, when conditions are added to a query, Mongoid considers each
-condition complete and independent from any other conditions potentially
-present in the query. For example, calling ``in`` twice adds two separate
-``$in`` conditions:
-
-.. code-block:: ruby
-
- Band.in(name: ['a']).in(name: ['b'])
- => #{"$in"=>["a"]}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
- options: {}
- class: Band
- embedded: false>
-
-Some operator methods support building the condition incrementally. In this
-case, when an condition on a field which uses one of the supported operators
-is being added, if there already is a condition on the same field using the
-same operator, the operator expressions are combined according to the
-specified *merge strategy*.
-
-.. _merge-strategies:
-
-Merge Strategies
-----------------
-
-Mongoid provides three merge strategies:
-
-- **Override**: the new operator instance replaces any existing conditions on
- the same field using the same operator.
-- **Intersect**: if there already is a condition using the same operator on the
- same field, the values of the existing condition are intersected with the
- values of the new condition and the result is stored as the operator value.
-- **Union**: if there already is a condition using the same operator on the
- same field, the values of the new condition are added to the values of the
- existing condition and the result is stored as the operator value.
-
-The following snippet demonstrates all of the strategies, using ``in`` as the
-example operator:
-
-.. code-block:: ruby
-
- Band.in(name: ['a']).override.in(name: ['b'])
- => #{"$in"=>["b"]}}
- options: {}
- class: Band
- embedded: false>
-
- Band.in(name: ['a', 'b']).intersect.in(name: ['b', 'c'])
- => #{"$in"=>["b"]}}
- options: {}
- class: Band
- embedded: false>
-
- Band.in(name: ['a']).union.in(name: ['b'])
- => #{"$in"=>["a", "b"]}}
- options: {}
- class: Band
- embedded: false>
-
-The strategy is requested by calling ``override``, ``intersect`` or ``union``
-on a ``Criteria`` instance. The requested strategy applies to the next
-condition method called on the query. If the next condition method called does
-not support merge strategies, the strategy is reset, as shown in the following
-example:
-
-.. code-block:: ruby
-
- Band.in(name: ['a']).union.ne(name: 'c').in(name: ['b'])
- => #{"$in"=>["a"], "$ne"=>"c"}, "$and"=>[{"name"=>{"$in"=>["b"]}}]}
- options: {}
- class: Band
- embedded: false>
-
-Since ``ne`` does not support merge strategies, the ``union`` strategy was
-ignored and reset and when ``in`` was invoked the second time there was no
-strategy active.
-
-.. warning::
-
- Merge strategies currently assume the previous condition(s) have been added
- to the top level of the query, however this is not always the case
- (conditions may be nested under an ``$and`` clause). Using merge strategies
- with complex criteria may cause incorrect queries to be constructed.
- This misbehavior is `intended to be fixed in the future
- `_.
-
-
-Supported Operator Methods
---------------------------
-
-The following operator methods support merge strategies:
-
-- ``all``
-- ``in``
-- ``nin``
-
-The set of methods may be expanded in future releases of Mongoid. For
-future compatibility, only invoke a strategy method when the next method call
-is an operator that supports merge strategies.
-
-Note that the merge strategies are currently only applied when conditions are
-added through the designated methods. In the following example merge strategy
-is not applied because the second condition is added via ``where``, not via
-``in``:
-
-.. code-block:: ruby
-
- Band.in(foo: ['a']).union.where(foo: {'$in' => 'b'})
- => #{"$in"=>["a"]}, "$and"=>[{"foo"=>{"$in"=>"b"}}]}
- options: {}
- class: Band
- embedded: false>
-
-This behavior may change in a future release of Mongoid and should not be
-relied upon.
-
-In contrast, it does not matter how the existing query was built when a
-merge strategy-supporting operator method is invoked. In the following
-example, the first condition was added through ``where`` but the strategy
-mechanism still applies:
-
-.. code-block:: ruby
-
- Band.where(foo: {'$in' => ['a']}).union.in(foo: ['b'])
- => #{"$in"=>["a", "b"]}}
- options: {}
- class: Band
- embedded: false>
-
-Operator Value Expansion
-------------------------
-
-Operator methods that support merge strategies all take ``Array`` as their value
-type. Mongoid expands ``Array``-compatible types, such as a ``Range``,
-when they are used with these operator methods:
-
-.. code-block:: ruby
-
- Band.in(year: 1950..1960)
- => #{"$in"=>[1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960]}}
- options: {}
- class: Band
- embedded: false>
-
-Additionally, Mongoid has historically wrapped non-``Array`` values in arrays,
-as the following example demonstrates:
-
-.. code-block:: ruby
-
- Band.in(year: 1950)
- => #{"$in"=>[1950]}}
- options: {}
- class: Band
- embedded: false>
-
-
-Query Methods
-=============
-
-elem_match
-----------
-
-This matcher finds documents with array fields where one of the array values
-matches all of the conditions. For example:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :tours, type: Array
- end
-
- aerosmith = Band.create!(name: 'Aerosmith', tours: [
- {city: 'London', year: 1995},
- {city: 'New York', year: 1999},
- ])
-
- Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]
-
-``elem_match`` also works with embedded associations:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- embeds_many :tours
- end
-
- class Tour
- include Mongoid::Document
- field :city, type: String
- field :year, type: Integer
- embedded_in :band
- end
-
- dm = Band.create!(name: 'Depeche Mode')
- aerosmith = Band.create!(name: 'Aerosmith')
- Tour.create!(band: aerosmith, city: 'London', year: 1995)
- Tour.create!(band: aerosmith, city: 'New York', year: 1999)
-
- Band.elem_match(tours: {city: 'London'}).to_a # => [aerosmith]
-
-``elem_match`` does not work with non-embedded associations because MongoDB
-does not have joins - the conditions would be added to the collection
-that is the source of a non-embedded association rather than the collection
-of the association's target.
-
-``elem_match`` can also be used with recursively embedded associations,
-as the following example shows:
-
-.. code-block:: ruby
-
- class Tag
- include Mongoid::Document
- field :name, type: String
- recursively_embeds_many
- end
-
- root = Tag.create!(name: 'root')
- sub1 = Tag.new(name: 'sub1', child_tags: [Tag.new(name: 'subsub1')])
- root.child_tags << sub1
- root.child_tags << Tag.new(name: 'sub2')
- root.save!
-
- Tag.elem_match(child_tags: {name: 'sub1'}).to_a # => [root]
-
- root.child_tags.elem_match(child_tags: {name: 'subsub1'}).to_a # => [sub1]
-
-
-.. _projection:
-
-Projection
-==========
-
-Mongoid provides two projection operators: ``only`` and ``without``.
-
-
-.. _only:
-
-``only``
---------
-
-The ``only`` method retrieves only the specified fields from the database. This
-operation is sometimes called "projection".
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :label, type: String
-
- embeds_many :tours
- end
-
- class Tour
- include Mongoid::Document
-
- field :city, type: String
- field :year, type: Integer
-
- embedded_in :band
- end
-
- band = Band.only(:name).first
-
-Attempting to reference attributes which have not been loaded results in
-``Mongoid::Errors::AttributeNotLoaded``.
-
-.. code-block:: ruby
-
- band.label
- #=> raises Mongoid::Errors::AttributeNotLoaded
-
-Even though Mongoid currently allows writing to attributes that have not
-been loaded, such writes will not be persisted
-(`MONGOID-4701 `_) and
-should therefore be avoided.
-
-``only`` can also be used with embedded associations:
-
-.. code-block:: ruby
-
- band = Band.only(:name, 'tours.year').last
- # => #
-
- band.tours.first
- # => #
-
-.. note::
-
- Server versions 4.2 and lower allowed projecting both an association and
- the association's fields in the same query, as follows:
-
- .. code-block:: ruby
-
- band = Band.only(:tours, 'tours.year').last
-
- The most recent projection specification overrides the earlier one.
- For example, the above query was equivalent to:
-
- .. code-block:: ruby
-
- band = Band.only('tours.year').last
-
- Server versions 4.4 and higher prohibit specifying an association and its
- fields in projection in the same query.
-
-``only`` can be specified with referenced associations (has_one, has_many,
-has_and_belongs_to_many) but is currently ignored for referenced associations -
-all fields of referenced associations will be loaded
-(`MONGOID-4704 `_).
-
-Note that if a document has ``has_one`` or ``has_and_belongs_to_many`` associations,
-the fields with foreign keys must be included in the list of attributes
-loaded with ``only`` for those associations to be loaded. For example:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
-
- has_and_belongs_to_many :managers
- end
-
- class Manager
- include Mongoid::Document
-
- has_and_belongs_to_many :bands
- end
-
- band = Band.create!(name: 'Astral Projection')
- band.managers << Manager.new
-
- Band.where(name: 'Astral Projection').only(:name).first.managers
- # => []
-
- Band.where(name: 'Astral Projection').only(:name, :manager_ids).first.managers
- # => [#]
-
-
-.. _without:
-
-``without``
------------
-
-The opposite of ``only``, ``without`` causes the specified fields to be omitted:
-
-.. code-block:: ruby
-
- Band.without(:name)
- # =>
- # #{"name"=>0}}
- # class: Band
- # embedded: false>
-
-Because Mongoid requires the ``_id`` field for various operations, it (as well
-as its ``id`` alias) cannot be omitted via ``without``:
-
-.. code-block:: ruby
-
- Band.without(:name, :id)
- # =>
- # #{"name"=>0}}
- # class: Band
- # embedded: false>
-
- Band.without(:name, :_id)
- # =>
- # #{"name"=>0}}
- # class: Band
- # embedded: false>
-
-
-.. _ordering:
-
-Ordering
-========
-
-Mongoid provides the ``order`` method on ``Criteria`` objects and its alias,
-``order_by``, to specify the ordering of documents. These methods take a
-hash indicating which fields to order the documents by, and whether to use
-ascending or descending order for each field.
-
-.. code-block:: ruby
-
- Band.order(name: 1)
- # => #{"name"=>1}}
- # class: Band
- # embedded: false>
-
- Band.order_by(name: -1, description: 1)
- # => #{"name"=>-1, "description"=>1}}
- # class: Band
- # embedded: false>
-
- Band.order_by(name: :desc, description: 'asc')
- # => #{"name"=>-1, "description"=>1}}
- # class: Band
- # embedded: false>
-
-The direction may be specified as integers ``1`` and ``-1`` for ascending
-and descending, respectively, or as symbols ``:asc`` and ``:desc``, or as
-strings ``"asc"`` and ``"desc"``.
-
-Alternatively, ``order`` accepts an array of two-element arrays specifying
-the ordering. Field names and directions may be strings or symbols.
-
-.. code-block:: ruby
-
- Band.order([['name', 'desc'], ['description', 'asc']])
-
- Band.order([[:name, :desc], [:description, :asc]])
-
-Another way of providing the order is to use ``#asc`` and ``#desc`` methods
-on symbols, as follows:
-
-.. code-block:: ruby
-
- Band.order(:name.desc, :description.asc)
-
-The arguments can be provided as a string using SQL syntax:
-
-.. code-block:: ruby
-
- Band.order('name desc, description asc')
-
-Finally, there are ``asc`` and ``desc`` methods that can be used instead of
-``order``/``order_by``:
-
-.. code-block:: ruby
-
- Band.asc('name').desc('description')
- # => #{"name"=>1, "description"=>-1}}
- class: Band
- embedded: false>
-
-``order`` calls can be chained, in which case the oldest calls define the
-most significant criteria and the newest calls define the least significant
-ones (since in Ruby hashes maintain the order of their keys):
-
-.. code-block:: ruby
-
- Band.order('name desc').order('description asc')
- # => #{"name"=>-1, "description"=>1}}
- class: Band
- embedded: false>
-
-This can sometimes lead to surprising results if there are scopes, including
-the default scope, that use ``order``/``order_by``. For example, in the
-following snippet bands are ordered by name first because the order in the
-default scope takes precedence over the order given in the query, due to
-the default scope being evaluated first:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :year, type: Integer
-
- default_scope -> { order(name: :asc) }
- end
-
- Band.order(year: :desc)
- # => #{"name"=>1, "year"=>-1}}
- class: Band
- embedded: false>
-
-
-Pagination
-==========
-
-Mongoid provides the pagination operators ``limit``, ``skip``, and ``batch_size`` on ``Criteria``.
-
-.. _limit:
-
-``limit``
----------
-
-``limit`` sets the total number of documents to be returned by a query:
-
-.. code-block:: ruby
-
- Band.limit(5)
- # =>
- # #5}
- # class: Band
- # embedded: false>
-
-.. _skip:
-
-``skip``
---------
-
-``skip`` (alias: ``offset``) sets the number of query results to skip
-before returning documents. The ``limit`` value, if specified, will be applied
-after documents are skipped. When performing pagination, ``skip`` is recommended
-to be combined with :ref:`ordering ` to ensure consistent results.
-
-.. code-block:: ruby
-
- Band.skip(10)
- # =>
- # #10}
- # class: Band
- # embedded: false>
-
-.. _batch-size:
-
-``batch_size``
---------------
-
-When executing large queries, or when iterating over query results with an enumerator method such as
-``Criteria#each``, Mongoid automatically uses the `MongoDB getMore command
-`_ to load results in batches.
-The default ``batch_size`` is 1000, however you may set it explicitly:
-
-.. code-block:: ruby
-
- Band.batch_size(500)
- # =>
- # #500}
- # class: Band
- # embedded: false>
-
-
-Finding By ``_id``
-==================
-
-Mongoid provides the ``find`` method on ``Criteria`` objects to find documents
-by their ``_id`` values:
-
-.. code-block:: ruby
-
- Band.find('5f0e41d92c97a64a26aabd10')
- # => #
-
-The ``find`` method performs type conversion, if necessary, of the argument
-to the type declared in the model being queried for the ``_id`` field.
-By default, the ``_id`` type is ``BSON::ObjectId``, thus the query above
-is equivalent to:
-
-.. code-block:: ruby
-
- Band.find(BSON::ObjectId.from_string('5f0e41d92c97a64a26aabd10'))
- # => #
-
-.. note::
-
- When querying collections directly using the driver, type conversion is not
- automatically performed:
-
-.. code-block:: ruby
-
- Band.collection.find(_id: BSON::ObjectId.from_string('5f0e41d92c97a64a26aabd10')).first
- # => {"_id"=>BSON::ObjectId('5f0e41d92c97a64a26aabd10'), "name"=>"Juno Reactor"}
-
- Band.collection.find(_id: '5f0e41d92c97a64a26aabd10').first
- # => nil
-
-The ``find`` method can accept multiple arguments, or an array of arguments.
-In either case each of the arguments or array elements is taken to be an ``_id``
-value, and documents with all of the specified ``_id`` values are returned in
-an array:
-
-.. code-block:: ruby
-
- Band.find('5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e')
- # => [#,
- #]
-
- Band.find(['5f0e41d92c97a64a26aabd10', '5f0e41b02c97a64a26aabd0e'])
- # => [#,
- #]
-
-If the same ``_id`` value is given more than once, the corresponding document
-is only returned once:
-
-.. code-block:: ruby
-
- Band.find('5f0e41b02c97a64a26aabd0e', '5f0e41b02c97a64a26aabd0e')
- # => [#]
-
-The documents returned are *not* ordered, and may be returned in a different
-order from the order of provided ``_id`` values, as illustrated in the above
-examples.
-
-If any of the ``_id`` values are not found in the database, the behavior of
-``find`` depends on the value of the ``raise_not_found_error`` configuration
-option. If the option is set to ``true``, ``find`` raises
-``Mongoid::Errors::DocumentNotFound`` if any of the ``_id``\s are not found.
-If the option is set to ``false`` and ``find`` is given a single ``_id`` to
-find and there is no matching document, ``find`` returns ``nil``. If the
-option is set to ``false`` and ``find`` is given an array of ids to find
-and some are not found, the return value is an array of documents that were
-found (which could be empty if no documents were found at all).
-
-
-.. _additional-query-methods:
-
-Additional Query Methods
-========================
-
-Mongoid also has some helpful methods on criteria.
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Operation
- - Example
-
- * - ``Criteria#count``
-
- *Get the total number of documents matching a filter, or the total
- number of documents in a collection. Note this will always hit
- the database for the count.*
-
- *As of Mongoid 7.2, the* ``count`` *method uses the*
- ``count_documents`` *driver helper to obtain the accurate count.
- previously the* ``count`` *driver helper was used which used
- collection metadata and was thus not necessarily accurate (but
- may have returned the result faster). Use* ``estimated_count``
- *method to obtain an approximate number of documents in the collection
- quickly.*
-
- -
- .. code-block:: ruby
-
- Band.count
- Band.where(name: "Photek").count
-
- * - ``Criteria#estimated_count``
-
- *Get an approximate number of documents in the collection using the
- collection metadata. The* ``estimated_count`` *method does not accept
- query conditions; if any are given, it will raise*
- ``Mongoid::Errors::InvalidEstimatedCountCriteria``.
- *If a model defines a default scope,* ``estimated_count`` *must be
- called on the unscoped model*.
-
- -
- .. code-block:: ruby
-
- Band.count
- Band.where(name: "Photek").count
-
- class Contract
- include Mongoid::Document
-
- field :active, type: Boolean
-
- default_scope -> { where(active: true) }
- end
-
- Contract.estimated_count
- # => raises Mongoid::Errors::InvalidEstimatedCountCriteria
-
- Contract.unscoped.estimated_count
- # => 0
-
- * - ``Criteria#distinct``
-
- *Get a list of distinct values for a single field. Note this will always hit
- the database for the distinct values.*
-
- *This method accepts the dot notation, thus permitting referencing
- fields in embedded associations.*
-
- *This method respects :ref:`field aliases `,
- including those defined in embedded documents.*
-
- -
- .. code-block:: ruby
-
- Band.distinct(:name)
- Band.where(:fans.gt => 100000).
- distinct(:name)
-
- Band.distinct('cities.name')
-
- # Assuming an aliased field:
- class Manager
- include Mongoid::Document
- embedded_in :band
- field :name, as: :n
- end
-
- # Expands out to "managers.name" in the query:
- Band.distinct('managers.n')
-
- * - ``Criteria#each``
-
- *Iterate over all matching documents in the criteria.*
-
- -
- .. code-block:: ruby
-
- Band.where(members: 1).each do |band|
- p band.name
- end
-
- * - ``Criteria#exists?``
-
- *Determine if any matching documents exist. Will return true if there
- are 1 or more.*
-
- ``#exists?`` *now takes a number of argument types:*
-
- - ``Hash``: *A hash of conditions.*
- - ``Object``: *An _id to search for.*
- - ``false``/``nil``: *Always returns false.*
-
- -
- .. code-block:: ruby
-
- Band.exists?
- Band.where(name: "Photek").exists?
- Band.exists?(name: "Photek")
- Band.exists?(BSON::ObjectId('6320d96a3282a48cfce9e72c'))
- Band.exists?('6320d96a3282a48cfce9e72c')
- Band.exists?(false)
- Band.exists?(nil)
-
- * - ``Criteria#fifth``
-
- *Get the fifth document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.fifth
-
- * - ``Criteria#fifth!``
-
- *Get the fifth document for the given criteria, or raise an error if
- none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.fifth!
-
- * - ``Criteria#find_by``
-
- *Find a document by the provided attributes. If not found,
- raise an error or return nil depending on the value of the*
- ``raise_not_found_error`` *configuration option.*
-
- -
- .. code-block:: ruby
-
- Band.find_by(name: "Photek")
-
- Band.find_by(name: "Tool") do |band|
- band.impressions += 1
- end
-
- * - ``Criteria#find_or_create_by``
-
- *Find a document by the provided attributes, and if not found
- create and return a newly persisted one. Note that attributes provided in the arguments to
- this method will override any set in ``create_with``*.
-
- -
- .. code-block:: ruby
-
- Band.find_or_create_by(name: "Photek")
- Band.where(:likes.gt => 10).find_or_create_by(name: "Photek")
-
- ``find_or_create_by`` can be used on any scope, but in this case
- the criteria given by the scope and by ``find_or_create_by`` are
- combined. The following creates three bands:
-
- .. code-block:: ruby
-
- Band.find_or_create_by(name: "Photek")
- Band.where(name: "Photek").find_or_create_by(name: "Aerosmith")
- # creates Aerosmith again because there is no band whose name
- # is Photek and Aerosmith at the same time
- Band.where(name: "Photek").find_or_create_by(name: "Aerosmith")
-
- * - ``Criteria#find_or_initialize_by``
-
- *Find a document by the provided attributes, and if not found
- return a new one.*
-
- -
- .. code-block:: ruby
-
- Band.find_or_initialize_by(name: "Photek")
- Band.where(:likes.gt => 10).find_or_initialize_by(name: "Photek")
-
- * - ``Criteria#first|last``
-
- *Finds a single document given the provided criteria. Get a list of
- documents by passing in a limit argument. This method automatically adds
- a sort on _id. This can cause performance issues, so if the sort is
- undesirable, Criteria#take can be used instead.*
-
- -
- .. code-block:: ruby
-
- Band.first
- Band.where(:members.with_size => 3).first
- Band.where(:members.with_size => 3).last
- Band.first(2)
-
- * - ``Criteria#first!|last!``
-
- *Finds a single document given the provided criteria, or raises an error
- if none are found. This method automatically adds a sort on _id if no
- sort is given. This can cause performance issues, so if the sort is
- undesirable, Criteria#take! can be used instead.*
-
- -
- .. code-block:: ruby
-
- Band.first!
- Band.where(:members.with_size => 3).first!
- Band.where(:members.with_size => 3).last!
-
- * - ``Criteria#first_or_create``
-
- *Find the first document by the provided attributes, and if not found
- create and return a newly persisted one.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").first_or_create
-
- * - ``Criteria#first_or_create!``
-
- *Find the first document by the provided attributes, and if not found
- create and return a newly persisted one using* ``create!``.
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").first_or_create!
-
- * - ``Criteria#first_or_initialize``
-
- *Find the first document by the provided attributes, and if not found
- return a new one.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").first_or_initialize
-
- * - ``Criteria#for_js``
-
- *Find documents for a provided JavaScript expression, optionally with
- the specified variables added to the evaluation scope. The scope
- argument is supported in MongoDB 4.2 and lower.*
- *Prefer* :manual:`$expr ` *over* ``for_js``.
-
- -
- .. code-block:: ruby
-
- # All MongoDB versions
- Band.for_js("this.name = 'Tool'")
-
- # MongoDB 4.2 and lower
- Band.for_js("this.name = param", param: "Tool")
-
- * - ``Criteria#fourth``
-
- *Get the fourth document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.fourth
-
- * - ``Criteria#fourth!``
-
- *Get the fourth document for the given criteria, or raise an error if
- none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.fourth!
-
- * - ``Criteria#length|size``
-
- *Same as count but caches subsequent calls to the database*
-
- -
- .. code-block:: ruby
-
- Band.length
- Band.where(name: "FKA Twigs").size
-
- * - ``Criteria#pick``
-
- *Get the values from one document for the provided fields.
- Returns nil for unset fields and for non-existent fields.*
-
- *This method does not apply a sort to the documents, so it
- will not necessarily return the values from the first document.*
-
- *This method accepts the dot notation, thus permitting referencing
- fields in embedded associations.*
-
- *This method respects :ref:`field aliases `,
- including those defined in embedded documents.*
-
- -
- .. code-block:: ruby
-
- Band.all.pick(:name)
-
- Band.all.pick('cities.name')
-
- # Using the earlier definition of Manager,
- # expands out to "managers.name" in the query:
- Band.all.pick('managers.n')
-
-
- * - ``Criteria#pluck``
-
- *Get all the values for the provided field.
- Returns nil for unset fields and for non-existent fields.*
-
- *This method accepts the dot notation, thus permitting referencing
- fields in embedded associations.*
-
- *This method respects :ref:`field aliases `,
- including those defined in embedded documents.*
-
- -
- .. code-block:: ruby
-
- Band.all.pluck(:name)
- #=> ["Daft Punk", "Aphex Twin", "Ween"]
-
- Band.all.pluck('address.city')
- #=> ["Paris", "Limerick", "New Hope"]
-
- # Using the earlier definition of Manager,
- # expands out to "managers.name" in the query:
- Band.all.pluck('managers.n')
- #=> [ ["Berry Gordy", "Tommy Mottola"], [], ["Quincy Jones"] ]
-
- # Accepts multiple field arguments, in which case
- # the result will be returned as an Array of Arrays.
- Band.all.pluck(:name, :likes)
- #=> [ ["Daft Punk", 342], ["Aphex Twin", 98], ["Ween", 227] ]
-
- * - ``Criteria#read``
-
- *Sets the read preference for the criteria.*
-
- -
- .. code-block:: ruby
-
- Band.all.read(mode: :primary)
-
- * - ``Criteria#second``
-
- *Get the second document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.second
-
- * - ``Criteria#second!``
-
- *Get the second document for the given criteria, or raise an error if
- none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.second!
-
- * - ``Criteria#second_to_last``
-
- *Get the second to last document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.second_to_last
-
- * - ``Criteria#second_to_last!``
-
- *Get the second to last document for the given criteria, or raise an
- error if none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.second_to_last!
-
- * - ``Criteria#take``
-
- *Get a list of n documents from the database or just one if no parameter
- is provided.*
-
- *This method does not apply a sort to the documents, so it can return
- different document(s) than #first and #last.*
-
- -
- .. code-block:: ruby
-
- Band.take
- Band.take(5)
-
- * - ``Criteria#take!``
-
- *Get a document from the database or raise an error if none exist.*
-
- *This method does not apply a sort to the documents, so it can return
- different document(s) than #first and #last.*
-
- -
- .. code-block:: ruby
-
- Band.take!
-
- * - ``Criteria#tally``
-
- *Get a mapping of values to counts for the provided field.*
-
- *This method accepts the dot notation, thus permitting referencing
- fields in embedded associations.*
-
- *This method respects :ref:`field aliases `,
- including those defined in embedded documents.*
-
- -
- .. code-block:: ruby
-
- Band.all.tally(:name)
-
- Band.all.tally('cities.name')
-
- # Using the earlier definition of Manager,
- # expands out to "managers.name" in the query:
- Band.all.tally('managers.n')
-
- * - ``Criteria#third``
-
- *Get the third document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.third
-
- * - ``Criteria#third!``
-
- *Get the third document for the given criteria, or raise an error if
- none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.third!
-
- * - ``Criteria#third_to_last``
-
- *Get the third to last document for the given criteria.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.third_to_last
-
- * - ``Criteria#third_to_last!``
-
- *Get the third to last document for the given criteria, or raise an
- error if none exist.*
-
- *This method automatically adds a sort on _id if no sort is given.*
-
- -
- .. code-block:: ruby
-
- Band.third_to_last!
-
-
-Eager Loading
-=============
-
-Mongoid provides a facility to eager load documents
-from associations to prevent the n+1 issue when
-iterating over documents with association access. Eager loading is supported on
-all associations with the exception of polymorphic ``belongs_to``
-associations.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- has_many :albums
- end
-
- class Album
- include Mongoid::Document
- belongs_to :band
- end
-
- Band.includes(:albums).each do |band|
- p band.albums.first.name # Does not hit the database again.
- end
-
-
-Regular Expressions
-===================
-
-MongoDB, and Mongoid, allow querying documents by regular expressions.
-
-Given the following model definitions:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :description, type: String
- end
-
- Band.create!(name: 'Sun Project', description: "Sun\nProject")
-
-... we can query using simple Ruby regular expressions in a natural way:
-
-.. code-block:: ruby
-
- Band.where(name: /project/i).first
- # => #
-
-It is also possible to query using PCRE syntax by constructing
-``BSON::Regexp::Raw`` objects explicitly:
-
-.. code-block:: ruby
-
- Band.where(description: /\AProject/).first
- # => #
-
- Band.where(description: BSON::Regexp::Raw.new('^Project')).first
- # => nil
-
- Band.where(description: BSON::Regexp::Raw.new('^Project', 'm')).first
- # => #
-
-
-Conditions On Fields
-====================
-
-When a condition uses a field defined in the model, the value being specified
-in the condition is converted according to the rules of the field, if any.
-For example, consider the following model definition that contains a ``Time``
-field, a ``Date`` field and an implicit ``Object`` field, and also
-intentionally does not define a field called ``deregistered_at``:
-
-.. code-block:: ruby
-
- class Voter
- include Mongoid::Document
-
- field :born_on, type: Date
- field :registered_at, type: Time
- field :voted_at
- end
-
-Queries on ``born_on`` and ``registered_at`` fields using ``Date`` and ``Time``
-values, respectively, are straightforward:
-
-.. code-block:: ruby
-
- Voter.where(born_on: Date.today).selector
- # => {"born_on"=>2020-12-18 00:00:00 UTC}
-
- Voter.where(registered_at: Time.now).selector
- # => {"registered_at"=>2020-12-19 04:33:36.939788067 UTC}
-
-But, note the differences in behavior when providing a ``Date`` instance
-in all possible scenarios:
-
-.. code-block:: ruby
-
- Voter.where(born_on: Date.today).selector
- # => {"born_on"=>2020-12-18 00:00:00 UTC}
-
- Voter.where(registered_at: Date.today).selector
- # => {"registered_at"=>2020-12-18 00:00:00 -0500}
-
- Voter.where(voted_at: Date.today).selector
- # => {"voted_at"=>Fri, 18 Dec 2020}
-
- Voter.where(deregistered_at: Date.today).selector
- # => {"deregistered_at"=>2020-12-18 00:00:00 UTC}
-
-When using the ``registered_at`` field which is of type ``Time``, the date
-was interpreted to be in local time (as per the :ref:`configured time zone
-`). When using the ``born_on`` field which is of type ``Date``,
-the date was interpreted to be in UTC. When using the ``voted_at`` field
-which was defined without a type (hence implicitly as an ``Object``),
-the date was used unmodified in the constructed query. When using a
-nonexistent field ``deregistered_at`` the date was interpreted to be in UTC
-and converted to a time, matching the behavior of querying a ``Date`` field.
-
-
-Scoping
-=======
-
-Scopes provide a convenient way to reuse common criteria with more
-business domain style syntax.
-
-
-.. _named-scopes:
-
-Named Scopes
-------------
-
-Named scopes are simply criteria defined at class load that are referenced
-by a provided name. Just like normal criteria, they are lazy and chainable.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :country, type: String
- field :genres, type: Array
-
- scope :english, ->{ where(country: "England") }
- scope :rock, ->{ where(:genres.in => [ "rock" ]) }
- end
-
- Band.english.rock # Get the English rock bands.
-
-Named scopes can take procs and blocks for accepting parameters or
-extending functionality.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :country, type: String
- field :active, type: Boolean, default: true
-
- scope :named, ->(name){ where(name: name) }
- scope :active, ->{
- where(active: true) do
- def deutsch
- tap do |scope|
- scope.selector.store("origin" => "Deutschland")
- end
- end
- end
- }
- end
-
- Band.named("Depeche Mode") # Find Depeche Mode.
- Band.active.deutsch # Find active German bands.
-
-By default, Mongoid allows defining a scope that would shadow an existing
-class method, as the following example shows:
-
-.. code-block:: ruby
-
- class Product
- include Mongoid::Document
-
- def self.fresh
- true
- end
-
- scope :fresh, ->{ where(fresh: true) }
- end
-
-To have Mongoid raise an error when a scope would overwrite an existing class
-method, set the ``scope_overwrite_exception`` :ref:`configuration option
-` to ``true``.
-
-
-Default Scopes
---------------
-
-Default scopes can be useful when you find yourself applying the same
-criteria to most queries, and wish to specify these criteria as the default.
-Default scopes are procs that return criteria objects.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :active, type: Boolean
-
- default_scope ->{ where(active: true) }
- end
-
- Band.each do |band|
- # All bands here are active.
- end
-
-Specifying a default scope also initializes the fields of new models to
-the values given in the default scope, if the values are simple literals:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :active, type: Boolean
- field :num_tours, type: Integer
-
- default_scope ->{ where(active: true, num_tours: {'$gt' => 1}) }
- end
-
- # active is set, num_tours is not set
- Band.new # => #
-
-Note that if a default value is provided both in the field definition and
-in the default scope, the value in the default scope takes precedence:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :active, type: Boolean, default: true
-
- default_scope ->{ where(active: false) }
- end
-
- Band.new # => #
-
-Because a default scope initializes fields in new models as just described,
-defining a default scope with a dotted key and a simple literal value, while
-possible, is not recommended:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :tags, type: Hash
-
- default_scope ->{ where('tags.foo' => 'bar') }
- end
-
- Band.create!
- # => Created document: {"_id"=>BSON::ObjectId('632de48f3282a404bee1877b'), "tags.foo"=>"bar"}
- Band.create!(tags: { 'foo' => 'bar' })
- # => Created document: {"_id"=>BSON::ObjectId('632de4ad3282a404bee1877c'), "tags.foo"=>"bar", "tags"=>{"foo"=>"bar"}}
- Band.all.to_a
- # => [ #"bar"}> ]
-
-Mongoid 8 allows dotted keys to be used in Mongoid, and when creating a document,
-the scope is added as a dotted key in the attributes:
-
-.. code-block:: ruby
-
- Band.new.attribute
- # => {"_id"=>BSON::ObjectId('632de97d3282a404bee1877d'), "tags.foo"=>"bar"}
-
-Whereas when querying, Mongoid looks for an embedded document:
-
-.. code-block:: ruby
-
- Band.create!
- # => Created document: {"_id"=>BSON::ObjectId('632de48f3282a404bee1877b'), "tags.foo"=>"bar"}
- Band.where
- # => #"bar"}
- options: {}
- class: Band
- embedded: false>
- # This looks for something like: { tags: { "foo" => "bar" } }
- Band.count
- # => 0
-
-A workaround is to define the default scope as a complex query:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :tags, type: Hash
-
- default_scope ->{ where('tags.foo' => {'$eq' => 'bar'}) }
- end
-
- Band.create!(tags: { hello: 'world' })
- Band.create!(tags: { foo: 'bar' })
- # does not add a "tags.foo" dotted attribute
- Band.count
- # => 1
-
-You can tell Mongoid not to apply the default scope by using
-``unscoped``, which can be inline or take a block.
-
-.. code-block:: ruby
-
- Band.unscoped.where(name: "Depeche Mode")
- Band.unscoped do
- Band.where(name: "Depeche Mode")
- end
-
-You can also tell Mongoid to explicitly apply the default scope
-again later to always ensure it's there.
-
-.. code-block:: ruby
-
- Band.unscoped.where(name: "Depeche Mode").scoped
-
-If you are using a default scope on a model that is part of an association,
-you must reload the association to have scoping reapplied.
-This is important to note if you change a value of a document in the association
-that would affect its visibility within the scoped association.
-
-.. code-block:: ruby
-
- class Label
- include Mongoid::Document
- embeds_many :bands
- end
-
- class Band
- include Mongoid::Document
- field :active, default: true
- embedded_in :label
- default_scope ->{ where(active: true) }
- end
-
- label.bands.push(band)
- label.bands # [ band ]
- band.update_attribute(:active, false)
- label.bands # [ band ] Must reload.
- label.reload.bands # []
-
-.. note::
-
- After the default scope is applied, it is no longer distinguished from
- other query conditions. This can lead to surprising behavior when using
- ``or`` and ``nor`` operators in particular:
-
- .. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name
- field :active
- field :touring
-
- default_scope ->{ where(active: true) }
- end
-
- Band.where(name: 'Infected Mushroom')
- # =>
- # #true, "name"=>"Infected Mushroom"}
- # options: {}
- # class: Band
- # embedded: false>
-
- Band.where(name: 'Infected Mushroom').or(touring: true)
- # =>
- # #[{"active"=>true, "name"=>"Infected Mushroom"}, {"touring"=>true}]}
- # options: {}
- # class: Band
- # embedded: false>
-
- Band.or(touring: true)
- # =>
- # #[{"active"=>true}, {"touring"=>true}]}
- # options: {}
- # class: Band
- # embedded: false>
-
- In the last example, you might expect the two conditions
- (``active: true`` and ``touring: true``) to be combined with an ``$and``,
- but because the ``Band`` class already has the scope applied to it,
- it becomes one of the disjunction branches of the ``or``.
-
-
-Runtime Default Scope Override
-------------------------------
-
-You can use the ``with_scope`` method to change the default scope in a block
-at runtime:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :country, type: String
- field :genres, type: Array
-
- scope :english, ->{ where(country: "England") }
- end
-
- criteria = Band.with_scope(Band.english) do
- Band.all
- end
-
- criteria
- # =>
- # #"England"}
- # options: {}
- # class: Band
- # embedded: false>
-
-.. note::
-
- If with_scope calls are nested, when the nested with_scope block completes
- Mongoid 7 sets the current scope to nil instead of the parent scope.
- Mongoid 8 will set the current scope to the correct parent scope.
- To get Mongoid 8 behavior in Mongoid 7.4 and higher, set the
- ``Mongoid.broken_scoping`` global option to false.
-
-
-Class Methods
--------------
-
-Class methods on models that return criteria objects are also
-treated like scopes, and can be chained as well.
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
- field :name, type: String
- field :active, type: Boolean, default: true
-
- def self.active
- where(active: true)
- end
- end
-
- Band.active
-
-
-Queries + Persistence
-=====================
-
-Mongoid supports persistence operations off of criteria
-in a light capacity for when you want to expressively perform multi
-document inserts, updates, and deletion.
-
-.. warning::
-
- Criteria ordering and pagination conditions, including ``order``, ``limit``,
- ``offset``, and ``batch_size``, will be ignored on the following operations.
-
-.. list-table::
- :header-rows: 1
- :widths: 30 60
-
- * - Operation
- - Example
-
- * - ``Criteria#create``
-
- *Create a newly persisted document.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").create
-
- * - ``Criteria#create!``
-
- *Create a newly persisted document and raise an exception on validation failure.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").create!
-
- * - ``Criteria#build|new``
-
- *Create a new (unsaved) document.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").build
- Band.where(name: "Photek").new
-
- * - ``Criteria#update``
-
- *Update attributes of the first matching document.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").update(label: "Mute")
-
- * - ``Criteria#update_all``
-
- *Update attributes of all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(members: 2).update_all(label: "Mute")
-
- * - ``Criteria#add_to_set``
-
- *Perform an $addToSet on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").add_to_set(label: "Mute")
-
- * - ``Criteria#bit``
-
- *Perform a $bit on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").bit(likes: { and: 14, or: 4 })
-
- * - ``Criteria#inc``
-
- *Perform an $inc on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").inc(likes: 123)
-
- * - ``Criteria#pop``
-
- *Perform a $pop on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Photek").pop(members: -1)
- Band.where(name: "Photek").pop(members: 1)
-
- * - ``Criteria#pull``
-
- *Perform a $pull on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").pull(members: "Maynard")
-
- * - ``Criteria#pull_all``
-
- *Perform a $pullAll on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").
- pull_all(:members, [ "Maynard", "Danny" ])
-
- * - ``Criteria#push``
-
- *Perform a $push on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").push(members: "Maynard")
-
- * - ``Criteria#push_all``
-
- *Perform a $push with $each on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").
- push_all(members: [ "Maynard", "Danny" ])
-
- * - ``Criteria#rename``
-
- *Perform a $rename on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").rename(name: :title)
-
- * - ``Criteria#set``
-
- *Perform a $set on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").set(likes: 10000)
-
- * - ``Criteria#unset``
-
- *Perform a $unset on all matching documents.*
-
- -
- .. code-block:: ruby
-
- Band.where(name: "Tool").unset(:likes)
-
- * - ``Criteria#delete``
-
- *Deletes all matching documents in the database.*
-
- -
- .. code-block:: ruby
-
- Band.where(label: "Mute").delete
-
- * - ``Criteria#destroy``
-
- *Deletes all matching documents in the database while running callbacks for all.
- This loads all documents into memory and can be an expensive operation.*
-
- -
- .. code-block:: ruby
-
- Band.where(label: "Mute").destroy
-
-
-.. _query-cache:
-
-Query Cache
-===========
-
-The Ruby MongoDB driver versions 2.14 and above provide query caching functionality. When enabled, the
-query cache saves the results of previously executed find and aggregation
-queries and reuses them in the future instead of performing the queries again,
-thus increasing application performance and reducing database load.
-
-Please review the `driver query cache documentation
-`_
-for details about the driver's query cache behavior.
-
-The rest of this section assumes that driver 2.14.0 or later is being used.
-
-
-Enabling Query Cache
---------------------
-
-The query cache may be enabled by using the driver's namespace or Mongoid's
-namespace.
-
-
-.. _enabling-query-cache-automatically:
-
-Enabling Query Cache Automatically
-----------------------------------
-
-The MongoDB Ruby Driver provides middleware to automatically enable the query cache for
-Rack web requests and ActiveJob job runs. Please see the :ref:`Query Cache Rack Middleware
-` section on the configuration page for instructions.
-
-Note that the Query Cache Middleware does not apply to code executed outside web requests
-and/or jobs.
-
-
-.. _enabling-query-cache-manually:
-
-Enabling Query Cache Manually
------------------------------
-
-To enable the Query Cache manually for a code segment, use:
-
-.. code-block:: ruby
-
- Mongo::QueryCache.cache do
- # ...
- end
-
-The Query Cache can also be explicitly enabled and disabled, although we
-recommend to use the block form described above:
-
-.. code-block:: ruby
-
- begin
- Mongo::QueryCache.enabled = true
- # ...
- ensure
- Mongo::QueryCache.enabled = false
- end
-
-
-.. _query-cache-first-method:
-
-Caching the Result of ``#first``
---------------------------------
-
-Calling the ``first`` method on a model class imposes an ascending sort by
-the ``_id`` field on the underlying query. This may produce unexpected behavior
-with query caching.
-
-For example, when calling ``all`` on a model class and then ``first``,
-one would expect the second query to use the cached results from the first.
-However, because of the sort imposed on the second query, both methods
-will query the database and separately cache their results.
-
-.. code-block:: ruby
-
- Band.all.to_a
- #=> Queries the database and caches the results
-
- Band.first
- #=> Queries the database again because of the sort
-
-To use the cached results, call ``all.to_a.first`` on the model class.
-
-
-.. _load-async:
-
-Asynchronous Queries
-====================
-
-Mongoid allows running database queries asynchronously in the background.
-This can be beneficial when there is a need to get documents from different
-collections.
-
-In order to schedule an asynchronous query call the ``load_async`` method on a
-``Criteria``:
-
-.. code-block:: ruby
-
- class PagesController < ApplicationController
- def index
- @active_bands = Band.where(active: true).load_async
- @best_events = Event.best.load_async
- @public_articles = Article.where(public: true).load_async
- end
- end
-
-In the above example three queries will be scheduled for asynchronous execution.
-Results of the queries can be later accessed as usual:
-
-.. code-block:: html
-
-
- <%- @active_bands.each do -%>
- - <%= band.name %>
- <%- end -%>
-
-
-Even if a query is scheduled for asynchronous execution, it might be executed
-synchronously on the caller's thread. There are three possible scenarios depending
-on when the query results are being accessed:
-
-#. If the scheduled asynchronous task has been already executed, the results are returned.
-#. If the task has been started, but not finished yet, the caller's thread blocks until the task is finished.
-#. If the task has not been started yet, it is removed from the execution queue, and the query is executed synchronously on the caller's thread.
-
-.. note::
-
- Even though ``load_async`` method returns a ``Criteria`` object, you should not
- do any operations on this object except accessing query results. The query is
- scheduled for execution immediately after calling ``load_async``, therefore
- later changes to the ``Criteria`` object may not be applied.
-
-
-Configuring asynchronous query execution
-----------------------------------------
-
-Asynchronous queries are disabled by default. When asynchronous queries are
-disabled, ``load_async`` will execute the query immediately on the current thread,
-blocking as necessary. Therefore, calling ``load_async`` on criteria in this case
-is roughly the equivalent of calling ``to_a`` to force query execution.
-
-In order to enable asynchronous query execution, the following config options
-must be set:
-
-.. code-block:: yaml
-
- development:
- ...
- options:
- # Execute asynchronous queries using a global thread pool.
- async_query_executor: :global_thread_pool
- # Number of threads in the pool. The default is 4.
- # global_executor_concurrency: 4
diff --git a/docs/reference/rails-integration.txt b/docs/reference/rails-integration.txt
deleted file mode 100644
index 0a43d96dca..0000000000
--- a/docs/reference/rails-integration.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-.. _rails-integration:
-
-*****************
-Rails Integration
-*****************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Mongoid seamlessly integrates into Ruby on Rails applications.
-This page describes features that are automatically enabled in the context
-of a Rails application and Rails-related functionality which can be
-manually enabled.
-
-
-Configuration
-=============
-
-You can set Mongoid configuration options in your ``application.rb`` along with
-other Rails environment specific options by accessing config.mongoid. The
-``mongoid:config`` generator will create an initializer in
-``config/initializers/mongoid.rb`` which can also be used for configuring
-Mongoid. Note, though, that options set in your ``config/mongoid.yml`` will
-take precedence over options set elsewhere; it is recommended that whenever
-possible you use ``mongoid.yml`` as the default location for Mongoid
-configuration.
-
-.. code-block:: ruby
-
- module MyApplication
- class Application < Rails::Application
- config.mongoid.logger = Logger.new(STDERR, :warn)
- end
- end
-
-
-Model Preloading
-================
-
-In order to properly set up single collection inheritance, Mongoid needs to preload all
-models before every request in development mode. This can get slow, so if you are not
-using any inheritance it is recommended you turn this feature off.
-
-.. code-block:: ruby
-
- config.mongoid.preload_models = false
-
-
-Exceptions
-==========
-
-Similarly to ActiveRecord, Mongoid configures Rails to automatically convert
-certain exceptions to well-known HTTP status codes, as follows:
-
-.. code-block:: ruby
-
- Mongoid::Errors::DocumentNotFound : 404
- Mongoid::Errors::Validations : 422
-
-
-Controller Runtime Instrumentation
-==================================
-
-Mongoid provides time spent executing MongoDB commands (obtained via a
-driver command monitoring subscription) to Rails' instrumentation event
-``process_action.action_controller``. This time is logged together with view
-time like so:
-
-.. code-block:: none
-
- Completed 200 OK in 2739ms (Views: 12.6ms | MongoDB: 0.2ms)
-
-This logging is set up automatically.
-
-Note: the time indicated is the time taken by MongoDB cluster to execute
-MongoDB operations, plus the time taken to send commands and receive
-results from MongoDB over the network. It does not include time taken by
-the driver and Mongoid to generate the queries or type cast and otherwise
-process the results.
-
-Rake Tasks
-==========
-
-Mongoid provides the following rake tasks when used in a Rails environment:
-
-- ``db:create``: Exists only for dependency purposes, does not actually do anything.
-- ``db:create_indexes``: Reads all index definitions from the models and attempts to create them in the database.
-- ``db:remove_indexes``: Reads all secondary index definitions from the models.
-- ``db:drop``: Drops all collections in the database with the exception of the system collections.
-- ``db:migrate``: Exists only for dependency purposes, does not actually do anything.
-- ``db:purge``: Deletes all data, including indexes, from the database. Since 3.1.0
-- ``db:schema:load``: Exists only for framework dependency purposes, does not actually do anything.
-- ``db:seed``: Seeds the database from db/seeds.rb
-- ``db:setup``: Creates indexes and seeds the database.
-- ``db:test:prepare``: Exists only for framework dependency purposes, does not actually do anything.
diff --git a/docs/reference/sessions.txt b/docs/reference/sessions.txt
deleted file mode 100644
index 4faf35c078..0000000000
--- a/docs/reference/sessions.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-.. _sessions:
-
-********
-Sessions
-********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-You can use sessions with Mongoid in a similar way that you would execute a transaction in ActiveRecord.
-Namely, you can call a method, ``#with_session`` on a model class or on an instance of a model and execute
-some operations in a block. All operations in the block will be executed in the context of single session.
-Please see the MongoDB Ruby driver documentation for what session options are available.
-
-Please note the following limitations of sessions:
-
-- Sessions cannot be shared across threads; sessions are not thread-safe. This is consistent with the Ruby driver's support for sessions.
-
-- Sessions cannot be nested. You cannot called ``#with_session`` on a model class or a model instance within the block passed to the ``#with_session`` method on another model class or model instance.
-
-- All model classes and instances used within the session block must use the same driver client. For example, if you have specified different ``storage_options`` for another model used in the block than that of the model class or instance on which ``#with_session`` is called, you will get an error.
-
-Using a Session via Model#with_session
-======================================
-
-Call ``#with_session`` on a model class and pass it session options to execute a block in the context
-of a session.
-
-.. code-block:: ruby
-
- Person.with_session(causal_consistency: true) do
- Person.create!
- person = Person.first
- person.name = "Emily"
- person.save
- end
-
-
-Using a Session via model#with_session
-======================================
-
-Call ``#with_session`` on a model instance and pass it session options to execute a block in the context
-of a session.
-
-.. code-block:: ruby
-
- person.with_session(causal_consistency: true) do
- person.username = 'Emily'
- person.save
- person.posts << Post.create!
- end
diff --git a/docs/reference/sharding.txt b/docs/reference/sharding.txt
deleted file mode 100644
index 6fd4152260..0000000000
--- a/docs/reference/sharding.txt
+++ /dev/null
@@ -1,146 +0,0 @@
-.. _sharding:
-
-**********************
-Sharding Configuration
-**********************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-Mongoid can assist with setting up collection sharding in sharded environments.
-
-
-.. _shard-keys:
-
-Declaring Shard Keys
-====================
-
-Shard keys can be declared on models using the ``shard_key`` macro:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- field :ssn
-
- shard_key ssn: 1
-
- # The collection must also have an index that starts with the shard key.
- index ssn: 1
- end
-
-Note that in order to shard a collection, the collection must have an index
-that starts with the shard key. Mongoid provides :ref:`index management
-` functionality, which the examples here take
-advantage of.
-
-Mongoid supports two syntaxes for declaring shard keys. The standard syntax
-follows the format of MongoDB `shardCollection shell helper
-`_
-and allows specifying ranged and hashed shard keys, compound shard keys and
-collection sharding options:
-
-.. code-block:: ruby
-
- shard_key ssn: 1
-
- shard_key ssn: 1, country: 1
-
- shard_key ssn: :hashed
-
- shard_key {ssn: :hashed}, unique: true
-
-The alternative is the shorthand syntax, in which only the keys are given.
-This syntax only supports ranged shard keys and does not allow options to
-be specified:
-
-.. code-block:: ruby
-
- shard_key :ssn
-
- shard_key :ssn, :country
-
-``shard_key`` macro can take the name of a ``belongs_to`` association in
-place of a field name, in which case Mongoid will use the foreign key
-configured in the association as the field name:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
-
- belongs_to :country
-
- # Shards by country_id.
- shard_key country: 1
-
- # The collection must also have an index that starts with the shard key.
- index country: 1
- end
-
-The shard key may also reference a field in an embedded document, by using
-the "." character to delimit the field names:
-
-.. code-block:: ruby
-
- shard_key "location.x" => 1, "location.y" => 1
-
- shard_key "location.x", "location.y"
-
-.. note::
-
- Because the "." character is used to delimit fields in embedded documents,
- Mongoid does not currently support shard key fields that themselves
- literally contain the "." character.
-
-.. note::
-
- If a model declares a shard key, Mongoid expects the respective collection
- to be sharded with the specified shard key. When reloading models, Mongoid
- will provide the shard key in addition to the ``id`` field value to the
- ``find`` command to improve query performance, especially on `geographically
- distributed sharded clusters `_.
- If the collection is not sharded with the specified shard key, queries
- may produce incorrect results.
-
-
-.. _sharding-management:
-
-Sharding Management Rake Tasks
-==============================
-
-To shard collections in the database according to the shard keys defined in
-the models, run the ``db:mongoid:shard_collections`` Rake task.
-If necessary, run the ``db:mongoid:create_indexes`` Rake task prior to
-sharding collections:
-
-.. code-block:: bash
-
- rake db:mongoid:create_indexes
- rake db:mongoid:shard_collections
-
-.. note::
-
- Like with index management rake tasks, sharding management rake tasks
- generally do not stop and fail when they encounter the problem with a
- particular model class. Instead they log the problem (to the configured
- Mongoid logger) at an appropriate level and continue with the next model.
- When Mongoid is used in a Rails application, this means the results of
- the rake task execution will generally be found in the per-environment
- log file like ``log/development.log``.
-
-.. note::
-
- When performing schema-related operations in a sharded cluster, such as
- sharding collections as described in this document, or creating or dropping
- collections or databases, cluster nodes may end up with out of date local
- configuration-related cache data. Execute the `flushRouterConfig
- `_
- command on each ``mongos`` node to clear these caches.
diff --git a/docs/reference/text-search.txt b/docs/reference/text-search.txt
deleted file mode 100644
index b7c3013de6..0000000000
--- a/docs/reference/text-search.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-.. _text-search:
-
-***********
-Text Search
-***********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-
-MongoDB provides :manual:`text indexes `
-to support text search queries on string content. Text indexes
-can include any field whose value is a string or an array of
-string elements.
-
-.. note::
-
- MongoDB Atlas also provides
- `Atlas Search `_
- which is a more powerful and flexible text search solution.
- The rest of this section discusses text indexes and not Atlas Search.
-
-To perform text search with Mongoid, follow these steps:
-
-1. Define a text index on a model.
-2. Create the text index on the server.
-3. Build a text search query.
-
-
-Defining Text Search Index
---------------------------
-
-Index definition through Mongoid is described in detail on the :ref:`indexes
-` page. Text search indexes are described in detail
-under `text indexes `_
-in the MongoDB manual. Below is an example definition of a Band model with
-a text index utilizing the description field:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :description, type: String
-
- index description: 'text'
- end
-
-Note that the index type (``text``) must be given as a string, not as a symbol.
-
-
-Creating Text Index
--------------------
-
-To create the index, invoke the ``db:mongoid:create_indexes`` Rake task:
-
-.. code-block:: ruby
-
- bundle exec rake db:mongoid:create_indexes
-
-
-Querying Using Text Index
--------------------------
-
-To find bands whose description contains "ounces" or its variations, use the
-`$text operator `_:
-
-.. code-block:: ruby
-
- Band.where('$text' => {'$search' => 'ounces'}).to_a
- # => [#]
-
-Note that the description contains the word "ounce" even though the search
-query was "ounces".
-
-Note also that when performing text search, the name of the field is not
-explicitly specified - ``$text`` operator searches all fields indexed with
-the text index.
diff --git a/docs/reference/transactions.txt b/docs/reference/transactions.txt
deleted file mode 100644
index ecf2465ea1..0000000000
--- a/docs/reference/transactions.txt
+++ /dev/null
@@ -1,232 +0,0 @@
-.. _transactions:
-
-************
-Transactions
-************
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Version 4.0 of the MongoDB server introduces
-`multi-document transactions `_.
-(Updates to multiple fields within a single document are atomic in all
-versions of MongoDB). Transactions require a non-standalone MongoDB topology
-and Ruby driver version 2.6 or higher. A higher level transaction API requires
-Mongoid version 9.0 or higher, while a lower level API requires Mongoid
-version 6.4 or higher.
-
-Using Transactions
-==================
-
-Higher Level API
-----------------
-
-A transaction can be started by calling the ``transaction`` method on an instance
-of a Mongoid document class, on a Mongoid document class, on or ``Mongoid`` module:
-
-.. code-block:: ruby
-
- Band.transaction do
- Band.create(title: 'Led Zeppelin')
- end
-
- band = Band.create(title: 'Deep Purple')
- band.transaction do
- band.active = false
- band.save!
- end
-
- Mongoid.transaction do
- band.destroy
- end
-
-When the ``transaction`` method is called, Mongoid does the following:
-
-* creates a session on a client that is used by the receiver of the
- ``transaction`` method call;
-* starts a transaction on the session;
-* executes the given block;
-* commits the transaction if no exception raised in the block;
-
- * calls ``after_commit`` callbacks for all objects modified inside the transaction
-* aborts the transaction if an exception is raised in the block;
-
- * calls ``after_rollback`` callbacks for all objects modified inside the transaction
-* closes the session
-
-.. note::
-
- Since a transaction is tied to a particular client, _only_ operations on
- the same client will be in scope of the transaction. Therefore it
- is recommended that only objects that use the same client are used inside the
- ``transaction`` method block.
-
- .. code-block:: ruby
-
- class Author
- include Mongoid::Document
- store_in client: :encrypted_client
- end
-
- class User
- include Mongoid::Document
- store_in client: :encrypted_client
- end
-
- class Article
- include Mongoid::Document
- # This class uses the :default client
- end
-
- # Transaction is started on the :encrypted_client
- Author.transaction do
- # This operation uses the same client, so it is in the transaction
- Author.create!
- # This operation also uses the same client, so it is in the transaction
- User.create!
- # This operation uses a different client, so it is NOT in the transaction
- Article.create!
- end
-
-.. note::
- When ``transaction`` method is called on ``Mongoid`` module, the transaction
- is created using the ``:default`` client.
-
-Aborting Transaction
-~~~~~~~~~~~~~~~~~~~~
-
-Any exception raised inside the ``transaction`` method block aborts the
-transaction. Normally the raised exception passed on, except for the
-``Mongoid::Errors::Rollback``. This error should be raised if you want to
-explicitly abort the transaction without passing on an exception.
-
-Callbacks
-~~~~~~~~~
-
-Transaction API introduces two new callbacks - ``after_commit`` and ``after_rollback``.
-
-``after_commit`` callback is triggered for an object that was created, saved,
-or destroyed:
-
-* after transaction is committed if the object was modified inside the transaction;
-* after the object was persisted if the object was modified outside a transaction.
-
-.. note::
- In any case ``after_commit`` callback is triggered only after all other callbacks
- were executed successfully. Therefore, if the object is modified without a
- transaction, it is possible that the object was persisted, but ``after_commit``
- callback was not triggered (for example, an exception raised in ``after_save``
- callback).
-
-``after_rollback`` callback is triggered for an object that was created, saved,
-or destroyed inside a transaction if the transaction was aborted. ``after_rollback``
-is never triggered without a transaction.
-
-
-Lower Level API
----------------
-
-In order to start a transaction, the application must have a :ref:`session `.
-
-A transaction can be started by calling the ``start_transaction`` method on a session, which can be
-obtained by calling the ``with_session`` method on either a model class or instance:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- end
-
- Person.with_session do |session|
- session.start_transaction
- end
-
- person = Person.new
- person.with_session do |session|
- session.start_transaction
- end
-
-It is also possible to specify read concern, write concern and read preference
-when starting a transaction:
-
-.. code-block:: ruby
-
- Person.with_session do |session|
- session.start_transaction(
- read_concern: {level: :majority},
- write_concern: {w: 3},
- read: {mode: :primary})
- end
-
-A transaction may be committed or aborted. The corresponding methods to do so are
-``commit_transaction`` and ``abort_transaction``, again on the session instance:
-
-.. code-block:: ruby
-
- Person.with_session do |session|
- session.commit_transaction
- end
-
- Person.with_session do |session|
- session.abort_transaction
- end
-
-If a session ends with an open transaction,
-`the transaction is aborted `_.
-
-The transaction commit `can be retried `_
-if it fails. Here is the Ruby code to do so:
-
-.. code-block:: ruby
-
- begin
- session.commit_transaction
- rescue Mongo::Error => e
- if e.label?(Mongo::Error::UNKNOWN_TRANSACTION_COMMIT_RESULT_LABEL)
- retry
- else
- raise
- end
- end
-
-Note that in order to perform operations within the transaction, operations must use the same client
-that the session was initiated on. By default, all operations will be done on the default client:
-
-.. code-block:: ruby
-
- class Person
- include Mongoid::Document
- end
-
- class Post
- include Mongoid::Document
- end
-
- Person.with_session do |s|
- s.start_transaction
- Person.create!
- Person.create!
- Post.create!
- s.commit_transaction
- end
-
-To explicitly use a different client, use the ``with`` method:
-
-.. code-block:: ruby
-
- Post.with(client: :other) do
- Person.with(client: :other) do
- Person.with_session do |s|
- s.start_transaction
- Person.create!
- Person.create!
- Post.create!
- s.commit_transaction
- end
- end
- end
diff --git a/docs/reference/validation.txt b/docs/reference/validation.txt
deleted file mode 100644
index a855c00652..0000000000
--- a/docs/reference/validation.txt
+++ /dev/null
@@ -1,66 +0,0 @@
-.. _validation:
-
-**********
-Validation
-**********
-
-.. default-domain:: mongodb
-
-.. contents:: On this page
- :local:
- :backlinks: none
- :depth: 2
- :class: singlecol
-
-Mongoid includes ``ActiveModel::Validations`` to supply the basic
-validation plus an additional associated and uniqueness validator.
-
-See the `Active Record Validations
-`_
-Rails guide and `ActiveModel::Validations
-`_
-documentation for more information.
-
-Mongoid behaves slightly differently to Active Record when using ``#valid?``
-on already persisted data. Active Record's ``#valid?`` will run all
-validations whereas Mongoid's ``#valid?`` will only run validations on
-documents that are in memory as an optimization.
-
-
-``validates_uniqueness_of`` and ``:conditions`` Option
-=======================================================
-
-The ``:conditions`` option to ``validates_uniqueness_of`` can be used to
-provide additional conditions to add to the database query looking for
-identical documents. This option does not influence when the validation
-is executed because it is not considered when Mongoid retrieves the present
-value of the respective field from the model. Consider the following example:
-
-.. code-block:: ruby
-
- class Band
- include Mongoid::Document
-
- field :name, type: String
- field :year, type: Integer
-
- validates_uniqueness_of :name, conditions: -> { where(:year.gte => 2000) }
- end
-
- # OK
- Band.create!(name: "Sun Project", year: 2000)
-
- # Fails validation because there is a band with the "Sun Project" name
- # and year 2000 in the database, even though the model being created now
- # does not have a year.
- Band.create!(name: "Sun Project")
-
-
-Read preference with ``validates_uniqueness_of``
-================================================
-
-In order to validate the uniqueness of an attribute, Mongoid must check that
-the value for that attribute does not already exist in the database. If Mongoid
-queries a secondary member of the replica set, there is a possibility that it
-is reading stale data. Because of this, the queries used to check a
-``validates_uniqueness_of`` validation always use read preference ``primary``.
diff --git a/docs/release-notes.txt b/docs/release-notes.txt
deleted file mode 100644
index 271271030d..0000000000
--- a/docs/release-notes.txt
+++ /dev/null
@@ -1,31 +0,0 @@
-.. _release-notes:
-
-*************
-Release Notes
-*************
-
-.. default-domain:: mongodb
-
-.. toctree::
- :titlesonly:
-
- release-notes/upgrading
- release-notes/mongoid-9.0
- release-notes/mongoid-8.1
- release-notes/mongoid-8.0
- release-notes/mongoid-7.5
- release-notes/mongoid-7.4
- release-notes/mongoid-7.3
-
-Overview
---------
-
-See the following sections to learn more about upgrading Mongoid:
-
-- :ref:`Upgrading Mongoid `
-- :ref:`Mongoid 9.0 `
-- :ref:`Mongoid 8.1