diff --git a/source/release-notes.txt b/source/release-notes.txt index 27127103..67d813fa 100644 --- a/source/release-notes.txt +++ b/source/release-notes.txt @@ -11,11 +11,6 @@ Release Notes 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 -------- @@ -23,9 +18,4 @@ Overview See the following sections to learn more about upgrading Mongoid: - :ref:`Upgrading Mongoid ` -- :ref:`Mongoid 9.0 ` -- :ref:`Mongoid 8.1 ` -- :ref:`Mongoid 8.0 ` -- :ref:`Mongoid 7.5 ` -- :ref:`Mongoid 7.4 ` -- :ref:`Mongoid 7.3 ` \ No newline at end of file +- :ref:`Mongoid 9.0 ` \ No newline at end of file diff --git a/source/release-notes/mongoid-7.3.txt b/source/release-notes/mongoid-7.3.txt deleted file mode 100644 index 6e6f5868..00000000 --- a/source/release-notes/mongoid-7.3.txt +++ /dev/null @@ -1,310 +0,0 @@ -.. _mongoid-7.3: - -*********** -Mongoid 7.3 -*********** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -This page describes significant changes and improvements in Mongoid 7.3. -The complete list of releases is available `on GitHub -`_ and `in JIRA -`_; -please consult GitHub releases for detailed release notes and JIRA for -the complete list of issues fixed in each release, including bug fixes. - - -``delete`` Method Does Not Trigger Association Dependent Behavior ----------------------------------------------------------------------- - -**Breaking change:** In Mongoid 7.3, -:ref:`dependent behavior ` is not invoked -when the parent association is deleted using the ``delete`` method. -For example, after the following code snippet executes, in Mongoid 7.3 the -album will remain in the database: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - has_many :albums, dependent: :destroy - end - - class Album - include Mongoid::Document - - belongs_to :band - end - - band = Band.create! - album = Album.create!(band: band) - - # Does not delete the album from the database - band.delete - -Previous versions of Mongoid invoked dependent behavior when deleting parents. - -To invoke dependent behavior, use the ``destroy`` method: - -.. code-block:: ruby - - # Deletes the album from the database - band.destroy - -The behavior of Mongoid 7.3 is consistent with how ActiveRecord behaves. - - -``::Boolean`` Removed ---------------------- - -**Breaking change:** Mongoid 7.3 removes the global ``::Boolean`` class. - -This change should have no impact on classes that simply use ``Boolean`` -fields, as the ``Boolean`` class is aliased from ``Mongoid::Fields`` -(which is included in ``Mongoid::Document``). The following field definition -continues to work in 7.3 as it did in 7.2: - -.. code-block:: ruby - - class User - include Mongoid::Document - - field :verified, type: Boolean - end - -However, code that is not executed in the context of a class including -``Mongoid::Document`` may need to explicitly qualify ``Boolean`` references. -The following snippet fails with Mongoid 7.3 due to ``Boolean`` being -unqualified: - -.. code-block:: ruby - - class User - include Mongoid::Document - end - - User.field :verified, type: Boolean - -To fix it, use the fully-qualified ``Mongoid::Boolean`` class: - -.. code-block:: ruby - - User.field :verified, type: Mongoid::Boolean - -Note that ``class_eval`` is executed in the scope of the caller, not in -the scope of the class being modified. Thus even when using ``class_eval`` -it is necessary to fully qualify ``Mongoid::Boolean``: - -.. code-block:: ruby - - User.class_eval do - field :verified, type: Mongoid::Boolean - end - -Additionally, in Mongoid 7.2 ``::Boolean`` and ``Mongoid::Boolean`` were -different classes. In Mongoid 7.3 there is only one class which is -``Mongoid::Boolean``. - -It is possible to restore the global ``::Boolean`` class by executing in -your application: - -.. code-block:: ruby - - Boolean = Mongoid::Boolean - -Note that this aliases ``Mongoid::Boolean`` to ``::Boolean`` such that there -is still only a single Boolean class: - -.. code-block:: ruby - - # With Mongoid 7.3: - Boolean = Mongoid::Boolean - Boolean == Mongoid::Boolean - # => true - - # With Mongoid 7.2: - Boolean == Mongoid::Boolean - # => false - - -Selector Key Stringification ----------------------------- - -Minor change: Mongoid now converts symbol keys to string keys in the -``Criteria`` selectors. This applies to operators as well as hash literals. - -Mongoid 7.3 behavior: - -.. code-block:: ruby - - Band.and(year: {'$in': [2020]}) - # => - # #{"$in"=>[2020]}} - # options: {} - # class: Band - # embedded: false> - - Band.where(tag: {city: 1}) - # => - # #{"city"=>1}} - # options: {} - # class: Band - # embedded: false> - -Mongoid 7.2 behavior: - -.. code-block:: ruby - - Band.and(year: {'$in': [2020]}) - # => - # #{:$in=>[2020]}} - # options: {} - # class: Band - # embedded: false> - - Band.where(tag: {city: 1}) - # => - # #{:city=>1}} - # options: {} - # class: Band - # embedded: false> - - -Condition Combination Using ``$eq`` / ``$regex`` ------------------------------------------------- - -Minor change: when using the ``where``, ``and``, ``or``, and ``nor`` methods -on ``Criteria`` objects and providing multiple conditions on the same field -in the same argument using the symbol operator syntax, conditions may be -combined using ``$eq`` or ``$regex`` operators, as appropriate, instead of -``$and``. - -Mongoid 7.3 behavior: - -.. code-block:: ruby - - Band.where(year: 2020, :year.gt => 1960) - # => - # #{"$eq"=>2020, "$gt"=>1960}} - # options: {} - # class: Band - # embedded: false> - - Band.where(name: /A/, :name.ne => 'Astral') - # => - # #{"$regex"=>/A/, "$ne"=>"Astral"}} - # options: {} - # class: Band - # embedded: false> - -Mongoid 7.2 behavior: - -.. code-block:: ruby - - Band.where(year: 2020, :year.gt => 1960) - # => - # #2020, "$and"=>[{"year"=>{"$gt"=>1960}}]} - # options: {} - # class: Band - # embedded: false> - - Band.where(name: /A/, :name.ne => 'Astral') - # => - # #/A/, "$and"=>[{"name"=>{"$ne"=>"Astral"}}]} - # options: {} - # class: Band - # embedded: false> - -The ``$regex`` operator is used when the value is a regular expression, i.e. -an instance of ``Regexp`` or ``BSON::Regexp::Raw`` classes. - -When using the ``not`` method with multiple conditions provided in the same -argument, the conditions are kept together and negated as a group. - -Mongoid 7.3 behavior: - -.. code-block:: ruby - - Band.not(year: 2020, :year.gt => 1960) - # => - # #[{"$nor"=>[{"year"=>{"$eq"=>2020, "$gt"=>1960}}]}]} - # options: {} - # class: Band - # embedded: false> - -Mongoid 7.2 behavior: - -.. code-block:: ruby - - Band.not(year: 2020, :year.gt => 1960) - # => - # #{"$ne"=>2020}, "$and"=>[{"$nor"=>[{"year"=>{"$gt"=>1960}}]}]} - # options: {} - # class: Band - # embedded: false> - - -New Embedded Matching Operators -------------------------------- - -Mongoid 7.3 adds support for bitwise operators, ``$comment``, ``$mod`` and -``$type`` operators when :ref:`embedded matching `. - - -Unaliasing ``id`` Field ------------------------ - -It is now possible to :ref:`remove the id alias in models `, -to make ``id`` a regular field. - - -``Mongoid.purge!`` and ``Mongoid.truncate`` take the global overrides into account ----------------------------------------------------------------------------------- - -Minor change: ``Mongoid.purge!`` and ``Mongoid.truncate!`` now consider global -overrides set with ``Mongoid.override_database`` and ``Mongoid.override_client``. - -Mongoid 7.3 behavior: - -.. code-block:: ruby - - Mongoid.override_database("some_other_db") - Band.create!(name: "Garage") - Band.count # => 1 - Mongoid.purge! # or Mongoid.truncate! - Band.count # => 0 - -Mongoid 7.2 behavior: - -.. code-block:: ruby - - Mongoid.override_database("some_other_db") - Band.create!(name: "Garage") - Band.count # => 1 - Mongoid.purge! # or Mongoid.truncate! - Band.count # => 1 - - -``update_one`` Warnings in ``upsert`` -------------------------------------- - -Mongoid 7.3.5 fixes incorrect usage of the driver's ``update_one`` method from -Mongoid's ``upsert`` method. Mongoid's ``upsert`` actually performs a -replacing upsert, and Mongoid 7.3.5 and later correctly call ``replace_one``. diff --git a/source/release-notes/mongoid-7.4.txt b/source/release-notes/mongoid-7.4.txt deleted file mode 100644 index dd3af5e7..00000000 --- a/source/release-notes/mongoid-7.4.txt +++ /dev/null @@ -1,584 +0,0 @@ -.. _mongoid-7.4: - -*********** -Mongoid 7.4 -*********** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -This page describes significant changes and improvements in Mongoid 7.4. -The complete list of releases is available `on GitHub -`_ and `in JIRA -`_; -please consult GitHub releases for detailed release notes and JIRA for -the complete list of issues fixed in each release, including bug fixes. - -All behavior changes in Mongoid 7.4 must be explicitly requested by changing -the value of configuration options as detailed below. By default, -Mongoid 7.4 behaves the same as Mongoid 7.3. - - -Ruby Version Support --------------------- - -As of version 7.4, Mongoid supports Ruby 2.5+. -Support for Ruby 2.4 and earlier has been dropped. - - -Support for MongoDB 3.4 and Earlier Servers Deprecated ------------------------------------------------------- - -Mongoid 7.4 deprecates support for MongoDB 3.4 and earlier. -Mongoid 8 will require MongoDB 3.6 or newer. - - -Feature Flags Summary ---------------------- - -To ensure a stable upgrade path from Mongoid 7.3, Mongoid 7.4 -introduces feature flags which are further explained in the -sections below. - -To enable all new behavior in Mongoid 7.4, please use the following -:ref:`configuration options ` in your mongoid.yml file. -We recommend newly created apps to do this as well. - -.. code-block:: yaml - - development: - ... - options: - # Enable all new behavior in Mongoid 7.4 - legacy_triple_equals: false - object_id_as_json_oid: false - compare_time_by_ms: true - broken_aggregables: false - broken_updates: false - broken_and: false - broken_scoping: false - broken_alias_handling: false - legacy_pluck_distinct: false - - -Change ``===`` Operator To Match Ruby Semantics ------------------------------------------------ - -In Mongoid 7.4, the ``===`` operator on ``Mongoid::Document`` classes and -instances can be configured to behave the same way as it does in Ruby, -and is equivalent to calling ``is_a?`` on the right hand -side with the left hand side as the argument: - -.. code-block:: ruby - - ModelClass === instance - - # equivalent to: - instance.is_a?(ModelClass) - -In order to get this functionality, the ``Mongoid.legacy_triple_equals`` -option must be set to false. If it is set to true, which is the default for -Mongoid 7.4, the ``===`` operator will function as it did in Mongoid 7.3: -``===`` returned ``true`` for some cases when the equivalent Ruby -``===`` implementation returned false, as per the examples below. - -Mongoid 7.4 with ``Mongoid.legacy_triple_equals`` set to ``false`` behavior: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - has_many :members - end - - class CoverBand < Band - end - - class Member - include Mongoid::Document - - belongs_to :band - end - - band = Band.new - cover_band = CoverBand.new - - band === Band - # => false - - cover_band === Band - # => false - - Band === Band - # => false - - CoverBand === Band - # => false - - band.members === Array - # => false - - band.members === Mongoid::Association::Referenced::HasMany::Enumerable - # => false - -Mongoid 7.3 and 7.4 with ``Mongoid.legacy_triple_equals`` set to ``true`` -behavior: - -.. code-block:: ruby - - band === Band - # => true - - cover_band === Band - # => true - - Band === Band - # => true - - CoverBand === Band - # => true - - band.members === Array - # => true - - band.members === Mongoid::Association::Referenced::HasMany::Enumerable - # => true - -The standard invocation of ``===``, that is having the class on the left and -the instance on the right, works the same in Mongoid 7.4 as it did previously -and matches the core Ruby behavior: - -.. code-block:: ruby - - Band === band - # => true - - Band === cover_band - # => true - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.legacy_triple_equals`` option will - change to ``false``. - - -Return String ``_id`` Value (Hexadecimal) from ``BSON::ObjectId#as_json`` -------------------------------------------------------------------------- - -Mongoid 7.4 permits configuring the ``BSON::ObjectId#as_json`` method -to return the ``_id`` value as a hexadecimal string instead of the -``{"$oid" => "..."}`` hash it has returned in Mongoid 7.3 and previous -versions. - -When ``Mongoid.object_id_as_json_oid`` is set to ``false``, Mongoid will -delegate to ``bson-ruby`` implementation of ``BSON::ObjectId#as_json``. -In ``bson-ruby`` 4 the ``BSON::ObjectId#as_json`` method will continue -to return the hash ``{"$oid" => "..."}`` for backwards compatibility, but -in ``bson-ruby`` 5 the ``BSON::ObjectId#as_json`` method will return only -the hexadecimal ObjectId string. - -When ``Mongoid.object_id_as_json_oid`` is set to ``true``, Mongoid will -install an implementation of ``BSON::ObjectId#as_json`` which returns -the hash ``{"$oid" => "..."}`` as it did in Mongoid 7.3 and earlier. - -The behavior of ``as_json`` is summarized in the following table: - -.. list-table:: - :header-rows: 1 - :stub-columns: 1 - :class: compatibility-large no-padding - - * - ``Mongoid.object_id_as_json_oid`` value - - true - - false - - * - ``bson-ruby`` 4 - - ``{"$oid"=>"621ed7fda15d5d231594627c"}`` - - ``{"$oid"=>"621ed7fda15d5d231594627c"}`` - - * - ``bson-ruby`` 5 - - ``{"$oid"=>"621ed7fda15d5d231594627c"}`` - - ``"621ed7fda15d5d231594627c"`` - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.object_id_as_json_oid`` option will - change to ``false``. - - -Scoped Associations -------------------- - -Associations now support the ``:scope`` argument, yielding -:ref:`scoped associations `. - - -Compare Times With Millisecond Precision When Embedded Matching ---------------------------------------------------------------- - -Mongoid 7.4 with the ``Mongoid.compare_time_by_ms`` option set to ``true`` -will truncate the times to millisecond precision when comparing them while -performing embedded matching. - -Time objects in Ruby have nanosecond precision, whereas MongoDB server -can only store times with millisecond precision. Set the -``Mongoid.compare_time_by_ms`` option to ``true`` to truncate times to -millisecond precision when performing queries on already loaded embedded -associations (this is also called "embedded matching" and is done completely -in Ruby), to obtain the same query results when performing time comparisons -regardless of which documents are being queried. Setting this option to -``false`` will produce different results for queries on embedded associations -that are already loaded into memory vs queries on unloaded associations and -top-level models. - -The ``Mongoid.compare_time_by_ms`` option is set to ``false`` by default -in Mongoid 7.4 for backwards compatibility. - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.compare_time_by_ms`` option will - change to ``true``. - - -``count``, ``sum``, ``avg``, ``min``, ``max`` Ignore Sort If Not Limiting/Skipping ----------------------------------------------------------------------------------- - -The ``count``, ``sum``, ``avg``, ``min`` and ``max`` methods now omit the -sort stage from the generated aggregation pipeline if no skip or limit -is specified, because the results aren't affected by the sort order. -Example call that will now omit the sort stage and would potentially use -an index where it wouldn't before: - -.. code-block:: ruby - - Band.desc(:name).count - - -Return ``0`` When Aggregating Empty Result Sets ------------------------------------------------ - -Mongoid 7.4 with the ``Mongoid.broken_aggregables`` option set to ``false`` -will return ``0`` from the ``sum`` method over an empty result set, for example: - -.. code-block:: ruby - - Product.where(impossible_condition: true).sum(:price) - # => 0 - -Mongoid 7.3 and Mongoid 7.4 with the ``Mongoid.broken_aggregables`` option -set to ``true`` (the default) returns ``nil`` in this case. - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.broken_aggregables`` option will - change to ``false``. - - -Correct Update Behavior When Replacing Association --------------------------------------------------- - -Mongoid 7.4 with the ``Mongoid.broken_updates`` option set to ``false`` -will correctly persist an ``embeds_one`` association target that is set to nil -and then to a non-nil value, for example: - -.. code-block:: ruby - - class Canvas - include Mongoid::Document - - embeds_one :palette - end - - canvas.palette = palette - canvas.palette = nil - canvas.palette = palette - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.broken_aggregables`` -option set to ``true`` (the default), ``canvas.palette`` would be ``nil`` when -we would expect it to be ``palette``. - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.broken_updates`` option will - change to ``false`` - - -Correct Logical ``and`` Query Generation ----------------------------------------- - -Mongoid 7.4 with the ``Mongoid.broken_and`` option set to ``false`` -will preserve existing conditions when using ``and`` to add new conditions -to a query when the same operator is used on the same field multiple times. -For example, in the following query: - -.. code-block:: ruby - - Band.where(id: 1).and({year: {'$in' => [2020]}}, {year: {'$in' => [2021]}}).where(id: 2) - -Mongoid 7.4 with the ``Mongoid.broken_and`` option set to ``false`` will -generate the following criteria: - -.. code-block:: ruby - - #1, "year"=>{"$in"=>[2020]}, "$and"=>[{"year"=>{"$in"=>[2021]}}, {"_id"=>2}]} - options: {} - class: Band - embedded: false> - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.broken_and`` -option set to ``true`` (the default), the following criteria would be -generated instead which omit the {"$in" => [2021]} condition: - -.. code-block:: ruby - - 1, "year"=>{"$in"=>[2020]}, "$and"=>[{"_id"=>2}]} - options: {} - class: Band - embedded: false> - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.broken_and`` option will - change to ``false``. - - -Restore Parent Scope When Exiting ``with_scope`` Block ------------------------------------------------------- - -Mongoid 7.4 with the ``Mongoid.broken_scoping`` option set to ``false`` -will restore the parent scope when exiting a ``with_scope`` block. -For example: - -.. code-block:: ruby - - Band.with_scope(year: 2020) do - Band.with_scope(active: true) do - # ... - end - - # {year: 2020} condition is applied here - end - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.broken_scoping`` -option set to ``true`` (the default), once any ``with_scope`` block finishes, -all scopes are cleared: - -.. code-block:: ruby - - Band.with_scope(year: 2020) do - Band.with_scope(active: true) do - # ... - end - - # No scope is applied here - end - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.broken_scoping`` option will - change to ``false``. - - -Changes to ``distinct`` and ``pluck`` -------------------------------------- - -Respect Field Aliases In Embedded Documents When Using ``distinct`` and ``pluck`` -````````````````````````````````````````````````````````````````````````````````` - -When ``distinct`` and ``pluck`` are used with aliased fields in embedded -documents, the aliases can be expanded if the ``Mongoid.broken_alias_handling`` -option is set to ``false``. By default, for backwards compatibility, in -Mongoid 7.4 this option is set to true, yielding Mongoid 7.3 and earlier -behavior. Given the following definitions: - -.. code-block:: ruby - - class Band - include Mongoid::Document - embeds_many :managers - end - - class Manager - include Mongoid::Document - embedded_in :band - - field :name, as: :n - end - -Mongoid 7.4 behavior with ``Mongoid.broken_alias_handling`` set to ``false``: - -.. code-block:: ruby - - # Expands out to "managers.n" in the query: - Band.distinct('managers.name') - Band.pluck('managers.name') - -Mongoid 7.3 and 7.4 with ``Mongoid.broken_alias_handling`` set to ``true`` behavior: - -.. code-block:: ruby - - # Sends "managers.name" without expanding the alias: - Band.distinct('managers.name') - Band.pluck('managers.name') - -.. note:: - - The alias expansion for top-level fields has already been done by Mongoid 7.3. - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.broken_alias_handling`` option will - change to ``false``. - - -Demongoize Values Returned from ``pluck`` and ``distinct`` -`````````````````````````````````````````````````````````` - -Mongoid 7.4 with the ``Mongoid.legacy_pluck_distinct`` option set to ``false`` -will demongoize values returned from the ``pluck`` and ``distinct`` methods. -Given the following definitions: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - field :sales, type: BigDecimal - end - - Band.create!(sales: "1E2") - Band.create!(sales: "2E2") - -Mongoid 7.4 behavior with ``Mongoid.legacy_pluck_distinct`` set to ``false``: - -.. code-block:: ruby - - Band.pluck(:sales) - # => [0.1e3, 0.2e3] - Band.distinct(:sales) - # => [0.1e3, 0.2e3] - - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.legacy_pluck_distinct`` -option set to ``true`` (the default), the value returned from the pluck and -distinct methods will not be demongoized. For example: - -.. code-block:: ruby - - Band.pluck(:sales) - # => ["1E2", "2E2"] - Band.distinct(:sales) - # => ["1E2", "2E2"] - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.legacy_pluck_distinct`` option will - change to ``false``. - - -Localized Fields with ``pluck`` and ``distinct`` -```````````````````````````````````````````````` -Mongoid 7.4 with the ``Mongoid.legacy_pluck_distinct`` option set to ``false`` -changes the behavior of using ``pluck`` and ``distinct`` with localized fields. -Now, when retrieving a localized field using these methods, the translation for -the current locale will be returned. To get the full translations hash the -``_translations`` field can be used. Given the following definitions: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - field :name, localize: true - end - - I18n.locale = :en - band = Band.create!(name: 'english-name') - I18n.locale = :de - band.name = 'deutsch-name' - band.save! - -Mongoid 7.4 behavior with ``Mongoid.legacy_pluck_distinct`` set to ``false``: - -.. code-block:: ruby - - Band.pluck(:name) - # => ["deutsch-name"] - Band.pluck(:name_translations) - # => [{"en"=>"english-name", "de"=>"deutsch-name"}, {"en"=>"english-name", "de"=>"deutsch-name"}] - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.legacy_pluck_distinct`` -option set to ``true`` (the default), inputting a localized field returns the -full translations hash. Inputting the ``_translations`` field will return ``nil``. -For example: - -.. code-block:: ruby - - Band.pluck(:name) - # => [{"en"=>"english-name", "de"=>"deutsch-name"}, {"en"=>"english-name", "de"=>"deutsch-name"}] - Band.pluck(:name_translations) - # => [nil, nil] - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.legacy_pluck_distinct`` option will - change to ``false``. - - -Embedded Fields with ``pluck`` -`````````````````````````````` -Mongoid 7.4 with the ``Mongoid.legacy_pluck_distinct`` option set to ``false`` -returns the embedded values themselves, i.e. not inside a hash. Given the -following definitions: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - embeds_one :label - end - - class Label - include Mongoid::Document - - embedded_in :band - field :sales, type: BigDecimal - end - -Mongoid 7.4 behavior with ``Mongoid.legacy_pluck_distinct`` set to ``false``: - -.. code-block:: ruby - - Band.pluck("label.sales") - # => [0.1e3] - -In Mongoid 7.3 and earlier, and in 7.4 with the ``Mongoid.legacy_pluck_distinct`` -option set to ``true`` (the default), plucking embedded attributes returns them -inside a hash. For example: - -.. code-block:: ruby - - Band.pluck("label.sales") - # => [{"sales"=>"1E2"}] - -.. note:: - - In Mongoid 8.0, the default value of the ``Mongoid.legacy_pluck_distinct`` option will - change to ``false``. - - -``update_one`` Warnings in ``upsert`` -------------------------------------- - -Mongoid 7.4.1 fixes incorrect usage of the driver's ``update_one`` method from -Mongoid's ``upsert`` method. Mongoid's ``upsert`` actually performs a -replacing upsert, and Mongoid 7.4.1 and later correctly call ``replace_one``. diff --git a/source/release-notes/mongoid-7.5.txt b/source/release-notes/mongoid-7.5.txt deleted file mode 100644 index b02da6ed..00000000 --- a/source/release-notes/mongoid-7.5.txt +++ /dev/null @@ -1,273 +0,0 @@ -.. _mongoid-7.5: - -*********** -Mongoid 7.5 -*********** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -This page describes significant changes and improvements in Mongoid 7.5. -The complete list of releases is available `on GitHub -`_ and `in JIRA -`_; -please consult GitHub releases for detailed release notes and JIRA for -the complete list of issues fixed in each release, including bug fixes. - - -Ruby, JRuby and Rails Version Support -------------------------------------- - -Mongoid 7.5 deprecates support for Ruby 2.5, JRuby 9.2 and Rails 5.1. -Mongoid 8 will require Ruby 2.6 or newer, JRuby 9.3 or newer and Rails 5.2 or -newer. - - -Feature Flags Summary ---------------------- - -To ensure a stable upgrade path from Mongoid 7.4, Mongoid 7.5 -introduces feature flags which are further explained in the -sections below. - -To enable all new behavior in Mongoid 7.5, please use the following -:ref:`configuration options ` in your mongoid.yml file. -We recommend newly created apps to do this as well. - -.. code-block:: yaml - - development: - ... - options: - # Enable all new behavior in Mongoid 7.5 - legacy_attributes: false - overwrite_chained_operators: false - -In addition, please refer to the release notes of earlier 7.x versions for -feature flags introduced in each version. For clarity, Mongoid 7.5 does -not switch the behavior of any previously introduced feature flag. - - -Implemented ``Criteria#take/take!`` Method ------------------------------------------- - -Mongoid 7.5 introduces the ``#take`` method which returns a document -or a set of documents from the database without ordering by ``_id``: - -.. code:: ruby - - class Band - include Mongoid::Document - end - - Band.create! - Band.create! - - Band.take - # => # - Band.take(2) - # => [ #, # ] - -If a parameter is given to ``#take``, an array of documents is returned. If no parameter is -given, a singular document is returned. - -The ``#take!`` method functions the same as calling ``#take`` without arguments, -but raises an DocumentNotFound error instead of returning nil if no documents -are found. - -.. code:: ruby - - Band.take! - # => # - -Note that the ``#take/take!`` methods do not apply a sort to the view before -retrieving the documents from the database, and therefore they may return different -results than the ``#first`` and ``#last`` methods. ``#take`` is equivalent to -calling ``#first`` or ``#last`` with the ``{ id_sort: :none }`` option. This -option has been deprecated in Mongoid 7.5 and it is recommended to use ``#take`` -instead going forward. Support for the ``:id_sort`` option will be dropped in -Mongoid 8. - - -Force the ``attributes`` Method to Always Return a ``Hash`` ------------------------------------------------------------ - -Mongoid 7.5 with the ``Mongoid.legacy_attributes`` option set to ``false`` -will always return a ``Hash`` when calling the ``attributes`` method. -For example: - -.. code-block:: ruby - - class Band - include Mongoid::Document - - field :name - end - - band = Band.create!(name: "The Rolling Stones") - p band.attributes.class - # => Hash - - band = Band.first - p band.attributes.class - # => Hash - -In Mongoid 7.4 and earlier, and in 7.5 with the ``Mongoid.legacy_attributes`` -option set to ``true``, the ``attributes`` method on a document will return a -``BSON::Document`` when retrieving that document from the database, but will -return a ``Hash`` when instantiating a new document: - -.. code-block:: ruby - - band = Band.create!(name: "The Rolling Stones") - p band.attributes.class - # => Hash - - band = Band.first - p band.attributes.class - # => BSON::Document - - -Deprecate ``:id_sort`` Option and Support ``limit`` on ``#first/last`` ----------------------------------------------------------------------- - -Mongoid 7.5 deprecates the ``:id_sort`` keyword argument for the -``Criteria#first`` and ``Criteria#last`` methods. Please use ``Criteria#take`` -to retrieve documents without sorting by id. - -The ``first`` and ``last`` methods now take the number of documents to return -as a positional argument, mirroring the functionality of Ruby's ``Enumerable`` -method and ActiveRecord's ``first`` and ``last`` methods. Both invocations -(with limit as a positional arguments and with the ``:id_sort`` option) remain -supported in Mongoid 7.x, but the ``:id_sort`` invocation will be removed in -Mongoid 8. - -.. code:: ruby - - Band.first - # => # - Band.first(2) - # => [ #, # ] - Band.last - # => # - Band.last(2) - # => [#, #] - -When providing a limit, ``#first/last`` will return a list of documents, and -when not providing a limit (or providing ``nil``), a single document will be -returned. - -Note that the ``#first/last`` methods apply a sort on ``_id``, which can -cause performance issues. To get a document without sorting first, use the -``Critera#take`` method. - - -Combine Chained Operators Using ``and`` Instead of ``override`` ---------------------------------------------------------------- - -Mongoid 7.5 with the ``Mongoid.overwrite_chained_operators`` option set to ``false`` -will combine conditions that use the same operator and field using an ``and``. -For example, in the following query: - -.. code-block:: ruby - - Band.ne(name: "The Rolling Stones").ne(name: "The Beatles") - -Mongoid 7.5 with the ``Mongoid.overwrite_chained_operators`` option set to ``false`` -will generate the following criteria: - -.. code-block:: ruby - - #{"$ne"=>"The Rolling Stones"}, "$and"=>[{"name"=>{"$ne"=>"The Beatles"}}]} - options: {} - class: Band - embedded: false> - -In Mongoid 7.4 and earlier, and in 7.5 with the ``Mongoid.overwrite_chained_operators`` -option set to ``true``, the following criteria would be generated instead which -overwrites the first condition: - -.. code-block:: ruby - - #{"$ne"=>"The Beatles"}} - options: {} - class: Band - embedded: false> - -The following functions are affected by this change: - -- ``eq`` -- ``elem_match`` -- ``gt`` -- ``gte`` -- ``lt`` -- ``lte`` -- ``mod`` -- ``ne`` -- ``near`` -- ``near_sphere`` - -.. note:: - - In Mongoid 7.5 with the ``Mongoid.overwrite_chained_operators`` option set to - ``false``, nested keys in the generated selector will always be strings, - whereas in Mongoid 7.4 and earlier, and in 7.5 with the - ``Mongoid.overwrite_chained_operators`` option set to ``true``, nested keys in - the selector can be strings or symbols, depending on what was passed to the - operator. - - -``pluck`` Usage of ``map`` Deprecated -------------------------------------- - -Mongoid 7.5 deprecates the usage of ``map`` as pluck, as in the following -example: - -.. code-block:: ruby - - Band.all.map(:name) - - # Equivalent to: - Band.pluck(:name) - -This usage will no longer be supported in Mongoid 8, which will not accept -arguments to ``map``. - - -``Mongoid::Criteria`` cache deprecated --------------------------------------- - -The ability to cache individual criteria objects has been deprecated in Mongoid -7.5 and will be dropped in Mongoid 8. - -In order to get caching functionality, enable the Mongoid QueryCache. See the -section on :ref:`QueryCache ` for more details. - - -``Array#update_values`` and ``Hash#update_values`` deprecated -------------------------------------------------------------- - -The ``Array#update_values`` and ``Hash#update_values`` methods are deprecated in -Mongoid 7.5. It is recommended to use ActiveSupport's ``transform_values!`` -method instead. - - -``Document#to_a`` deprecated ----------------------------- - -The ``Document#to_a`` method is deprecated in Mongoid 7.5. - - -``update_one`` Warnings in ``upsert`` -------------------------------------- - -Mongoid 7.5 fixes incorrect usage of the driver's ``update_one`` method from -Mongoid's ``upsert`` method. Mongoid's ``upsert`` actually performs a -replacing upsert, and Mongoid 7.5 correctly calls ``replace_one``. diff --git a/source/release-notes/mongoid-8.0.txt b/source/release-notes/mongoid-8.0.txt deleted file mode 100644 index 553494b1..00000000 --- a/source/release-notes/mongoid-8.0.txt +++ /dev/null @@ -1,866 +0,0 @@ -.. _mongoid-8.0: - -*********** -Mongoid 8.0 -*********** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -This page describes significant changes and improvements in Mongoid 8.0. -The complete list of releases is available `on GitHub -`_ and `in JIRA -`_; -please consult GitHub releases for detailed release notes and JIRA for -the complete list of issues fixed in each release, including bug fixes. - - -Support for MongoDB 3.4 and Earlier Servers Dropped ---------------------------------------------------- - -Mongoid 8 requires MongoDB 3.6 or newer. Earlier server versions are not -supported. - - -Support for Ruby 2.5 Dropped ----------------------------- - -Mongoid 8 requires Ruby 2.6 or newer. Earlier Ruby versions are not supported. - - -Support for Rails 5.1 Dropped ------------------------------ - -Mongoid 8 requires Rails 5.2 or newer. Earlier Rails versions are not supported. - - -Default Option Values Changed ------------------------------ - -**Breaking change:** The following options have had their default values -changed in Mongoid 8.0: - -- ``:broken_aggregables`` => ``false`` -- ``:broken_alias_handling`` => ``false`` -- ``:broken_and`` => ``false`` -- ``:broken_scoping`` => ``false`` -- ``:broken_updates`` => ``false`` -- ``:compare_time_by_ms`` => ``true`` -- ``:legacy_attributes`` => ``false`` -- ``:legacy_pluck_distinct`` => ``false`` -- ``:legacy_triple_equals`` => ``false`` -- ``:object_id_as_json_oid`` => ``false`` -- ``:overwrite_chained_operators`` => ``false`` - -Please refer to :ref:`configuration option ` for -the description and effects of each of these options. - - -``Decimal128``-backed ``BigDecimal`` Fields -------------------------------------------- - -Mongoid 8 introduces the ``map_big_decimal_to_decimal128`` feature flag, which -allows values assigned to a field of type ``BigDecimal`` to be stored as type -``String`` in the database for compatibility with Mongoid 7 and earlier. In -Mongoid 8 by default (with this feature flag turned on), values assigned to -fields of type ``BigDecimal`` are stored in the database as type -``BSON::Decimal128``. In Mongoid 7 and earlier, and in Mongoid 8 with this -feature flag turned off, values assigned to fields of type ``BigDecimal`` are -stored as Strings. See the section on :ref:`BigDecimal Fields ` -for more details. - - -Storing/Retrieving/Evolving Uncastable Values ---------------------------------------------- - -**Breaking change:** In Mongoid 8, Mongoid standardizes the storing, retrieving -and evolving of "uncastable values." On attempting to read or write an -uncastable value, a ``nil`` is returned or written instead. When attempting to -evolve an uncastable value, the inputted value is returned. See the section on -:ref:`Uncastable Values ` for more details. - -Some ``mongoize``, ``demongoize`` and ``evolve`` methods were also changed to -perform consistently with rails and the other ``mongoize``, ``demongoize`` and -``evolve`` methods. The following table shows the changes in functionality: - -.. list-table:: - :widths: 1 2 2 2 - :stub-columns: 1 - :header-rows: 1 - - * - Field Type - - Situation - - Previous Functionality - - New Functionality - - * - | Boolean - - | When a non-boolean string is assigned: "bogus value" - - | return ``false`` - - | return ``nil`` - - * - Array/Hash - - When a value that is not an array or hash is assigned - - raise ``InvalidValue`` error - - return ``nil`` - - * - | Set - - | When a value that is not a set is assigned: 1 - - | raise ``NoMethodError`` Exception: undefined method ``to_a`` for 1:Integer - - | return ``nil`` - - * - Regexp - - When persisting and reading a Regexp from the database - - return a ``BSON::Regexp::Raw`` - - return a ``Regexp`` - - * - | Time/DateTime - - | When assigning a bogus value: ``:bogus`` - - | raise ``NoMethodError`` Exception: undefined method ``to_i`` for :bogus:Symbol - - | return ``nil`` - - * - Time/DateTime - - When demongoizing a non-Time value: "bogus", ``Date.today`` - - raise ``NoMethodError`` Exception: undefined method ``getlocal`` for "bogus":String - - "bogus": return ``nil`` - - ``Date.today``: return ``Time/DateTime`` - - * - | Date - - | When assigning or demongoizing a bogus value: :bogus - - | raise ``NoMethodError`` Exception: undefined method ``year`` for :bogus:Symbol - - | return ``nil`` - - * - Time/DateTime/Date - - When demongoizing a valid string: "2022-07-14 14:45:51 -0400" - - raise ``NoMethodError`` Exception: undefined method ``getlocal`` for "2022-07-14 14:45:51 -0400":String - - return a ``Time/DateTime/Date`` - - * - | All Types - - | When an uncastable value is assigned or demongoized - - | undefined behavior, occasionally raise ``NoMethodError`` - - | return ``nil`` - - * - All Types - - When an uncastable value is evolved - - undefined behavior, occasionally raise ``NoMethodError`` - - return inputted value - -.. note:: - - The ``demongoize`` methods on container objects (i.e. Hash, Array) have not - changed to prevent bugs when modifying and saving those objects. See - https://jira.mongodb.org/browse/MONGOID-2951 for a longer discussion on these - bugs. - -Changes to the ``attributes_before_type_cast`` Hash ---------------------------------------------------- - -The ``attributes_before_type_cast`` hash has been changed to function more like -ActiveRecord: - -- On instantiation of a new model (without parameters), the - ``attributes_before_type_cast`` hash has the same contents as the - ``attributes`` hash. If parameters are passed to the initializer, those - values will be stored in the ``attributes_before_type_cast`` hash before - they are ``mongoized``. -- When assigning a value to the model, the ``mongoized`` value (i.e. when - assiging '1' to an Integer field, it is ``mongoized`` to 1) is stored in - the ``attributes`` hash, whereas the raw value (i.e. '1') is stored in the - ``attributes_before_type_cast`` hash. -- When saving, creating (i.e. using the ``create!`` method), or reloading the - model, the ``attributes_before_type_cast`` hash is reset to have the same - contents as the ``attributes`` hash. -- When reading a document from the database, the ``attributes_before_type_cast`` - hash contains the attributes as they appear in the database, as opposed to - their ``demongoized`` form. - - -Order of Callback Invocation ----------------------------- - -**Breaking change:** Mongoid 8.0 changes the order of _create and _save callback -invocation for documents with associations. - -Referenced associations (``has_one`` and ``has_many``): - -.. list-table:: - :header-rows: 1 - :widths: 50 50 - - * - Mongoid 8.0 - - Mongoid 7 - - * - | Parent :before_save - - | Parent :before_save - - * - Parent :around_save_open - - Parent :around_save_open - - * - | Parent :before_create - - | Parent :before_create - - * - Parent :around_create_open - - Parent :around_create_open - - * - | **Parent persisted in MongoDB** - - | **Parent persisted in MongoDB** - - * - Child :before_save - - Parent :around_create_close - - * - | Child :around_save_open - - | Parent :after_create - - * - Child :before_create - - Child :before_save - - * - | Child :around_create_open - - | Child :around_save_open - - * - - - Child :before_create - - * - | - - | Child :around_create_open - - * - **Child persisted in MongoDB** - - **Child persisted in MongoDB** - - * - | Child :around_create_close - - | Child :around_create_close - - * - Child :after_create - - Child :after_create - - * - | Child :around_save_close - - | Child :around_save_close - - * - Child :after_save - - Child :after_save - - * - | Parent :around_create_close - - | Parent :around_save_close - - * - Parent :after_create - - Parent :after_save - - * - | Parent :around_save_close - - | - - * - Parent :after_save - - - -Embedded associations (``embeds_one`` and ``embeds_many``): - -.. list-table:: - :header-rows: 1 - :widths: 50 50 - - * - Mongoid 8.0 - - Mongoid 7 - - * - | Parent :before_save - - | Child :before_save - - * - Parent :around_save_open - - Child :around_save_open - - * - | Parent :before_create - - | Child :around_save_close - - * - Parent :around_create_open - - Child :after_save - - * - | Child :before_save - - | Parent :before_save - - * - Child :around_save_open - - Parent :around_save_open - - * - | Child :before_create - - | Child :before_create - - * - Child :around_create_open - - Child :around_create_open - - * - | - - | Child :around_create_close - - * - - - Child :after_create - - * - | - - | Parent :before_create - - * - - - Parent :around_create_open - - * - | **Document persisted in MongoDB** - - | **Document persisted in MongoDB** - - * - Child :around_create_close - - - - * - | Child :after_create - - | - - * - Child :around_save_close - - - - * - | Child :after_save - - | - - * - Parent :around_create_close - - Parent :around_create_close - - * - | Parent :after_create - - | Parent :after_create - - * - Parent :around_save_close - - Parent :around_save_close - - * - | Parent :after_save - - | Parent :after_save - -``Changeable`` Module Behavior Made Compatible With ``ActiveModel::Dirty`` --------------------------------------------------------------------------- - -When updating documents, it is now possible to get updated attribute values -in ``after_*`` callbacks. This follows ActiveRecord/ActiveModel behavior. - -.. code-block:: ruby - - class Cat - include Mongoid::Document - - field :age, type: Integer - - after_save do - p self - p attribute_was(:age) - end - end - - a = Cat.create! - a.age = 2 - a.save! - -Mongoid 8.0 output: - -.. code-block:: ruby - - # - 2 - - -Mongoid 7 output: - -.. code-block:: ruby - - # - nil - -Notice that in 7 ``attribute_was(:age)`` returns the old attribute value, -while in 8.0 ``attribute_was(:age)`` returns the new value. - - -``*_previously_was``, ``previously_new_record?``, and ``previously_persisted?`` helpers ---------------------------------------------------------------------------------------- - -Mongoid 8.0 introduces ActiveModel-compatible ``*_previously_was`` helpers, -as well as ActiveRecord-compatible ``previously_new_record?`` and -``previously_persisted?`` helpers: - -.. code-block:: ruby - - class User - include Mongoid::Document - - field :name, type: String - field :age, type: Integer - end - - user = User.create!(name: 'Sam', age: 18) - user.previously_new_record? # => true - - user.name = "Nick" - user.save! - user.name_previously_was # => "Sam" - user.age_previously_was # => 18 - user.previously_new_record? # => false - - user.destroy - user.previously_persisted? # => true - - -Unknown Field Type Symbols/Strings Prohibited ---------------------------------------------- - -**Breaking change:** Mongoid 8 prohibits using symbols and strings as field -types when these symbols and strings do not map to a known type. Previously -such usage would create a field of type ``Object``. - -Mongoid 8 behavior: - -.. code-block:: ruby - - class User - include Mongoid::Document - - field :name, type: :bogus - # => raises Mongoid::Errors::InvalidFieldType - end - -Mongoid 7 behavior: - -.. code-block:: ruby - - class User - include Mongoid::Document - - field :name, type: :bogus - # Equivalent to: - field :name - end - - -``any_of`` Adds Multiple Arguments As Top-Level Conditions ----------------------------------------------------------- - -**Breaking change:** When ``any_of`` is invoked with multiple conditions, the -conditions are now added to the top level of the criteria, same as when -``any_of`` is invoked with a single condition. Previously when multiple -conditions were provided, and the criteria already had an ``$or`` operator, -the new conditions would be added to the existing ``$or`` as an additional -branch. - -Mongoid 8.0 behavior: - -.. code-block:: ruby - - Band.any_of({name: 'The Rolling Stones'}, {founded: 1990}). - any_of({members: 2}, {last_tour: 1995}) - # => - # #[{"name"=>"The Rolling Stones"}, {"founded"=>1990}], - # "$and"=>[{"$or"=>[{"members"=>2}, {"last_tour"=>1995}]}]} - # options: {} - # class: Band - # embedded: false> - - Band.any_of({name: 'The Rolling Stones'}, {founded: 1990}).any_of({members: 2}) - # => - # #[{"name"=>"The Rolling Stones"}, {"founded"=>1990}], "members"=>2} - # options: {} - # class: Band - # embedded: false> - -Mongoid 7 behavior: - -.. code-block:: ruby - - Band.any_of({name: 'The Rolling Stones'}, {founded: 1990}). - any_of({members: 2}, {last_tour: 1995}) - # => - # #[{"name"=>"The Rolling Stones"}, {"founded"=>1990}, - # {"members"=>2}, {"last_tour"=>1995}]} - # options: {} - # class: Band - # embedded: false> - - Band.any_of({name: 'The Rolling Stones'}, {founded: 1990}).any_of({members: 2}) - # => - # #[{"name"=>"The Rolling Stones"}, {"founded"=>1990}], "members"=>2} - # options: {} - # class: Band - # embedded: false> - - -``#pluck`` on Embedded Criteria Returns ``nil`` Values ------------------------------------------------------- - -Mongoid 8 fixes a bug where calling ``#pluck`` on a Mongoid::Criteria -for embedded documents discarded nil values. This behavior was -inconsistent with both the ``#pluck`` method in ActiveSupport and -with how ``#pluck`` works when reading documents from the database. - -Mongoid 8.0 behavior: - -.. code-block:: ruby - - class Address - include Mongoid::Document - - embedded_in :mall - - field :street, type: String - end - - class Mall - include Mongoid::Document - - embeds_many :addresses - end - - mall = Mall.create! - mall.addresses.create!(street: "Elm Street") - mall.addresses.create!(street: nil) - - # Pluck from embedded document criteria - mall.addresses.all.pluck(:street) - #=> ['Elm Street', nil] - -Mongoid 7 behavior, given the same setup: - -.. code-block:: ruby - - # Pluck from embedded document criteria - mall.addresses.all.pluck(:street) - #=> ['Elm Street'] - -For clarity, the following behavior is unchanged from Mongoid 7 to Mongoid 8.0: - -.. code-block:: ruby - - # Pluck from database - Mall.all.pluck('addresses.street') - #=> [ ['Elm Street', nil] ] - - # Pluck using ActiveSupport Array#pluck - mall.addresses.pluck(:street) - #=> ['Elm Street', nil] - - -Replaced ``Mongoid::Criteria#geo_spacial`` with ``#geo_spatial`` ----------------------------------------------------------------- - -The previously deprecated ``Mongoid::Criteria#geo_spacial`` method has been -removed in Mongoid 8. It has been replaced one-for-one with ``#geo_spatial`` -which was added in Mongoid 7.2.0. - - -Implemented ``.tally`` method on ``Mongoid#Criteria`` ------------------------------------------------------ - -Mongoid 8 implements the ``.tally`` method on ``Mongoid#Criteria``. ``tally`` -takes a field name as a parameter and returns a mapping from values to their -counts. For example, take the following model: - -.. code:: - - class User - include Mongoid::Document - field :age - end - -and the following documents in the database: - -.. code:: - - { _id: 1, age: 21 } - { _id: 2, age: 21 } - { _id: 3, age: 22 } - -Calling ``tally`` on the age field yields the following: - -.. code:: - - User.tally("age") - # => { 21 => 2, 22 => 1 } - -The ``tally`` method accepts the dot notation and field aliases. It also -allows for tallying localized fields. - - -Implemented ``.pick`` method on ``Mongoid#Criteria`` ------------------------------------------------------ - -Mongoid 8 implements the ``.pick`` method on ``Mongoid#Criteria``. ``pick`` -takes one or more field names as a parameter and returns the values for those -fields from one document. Consider the following model: - -.. code:: - - class User - include Mongoid::Document - field :age - end - -and the following documents in the database: - -.. code:: - - { _id: 1, age: 21 } - { _id: 2, age: 21 } - { _id: 3, age: 22 } - -Calling ``pick`` on the age field yields the following: - -.. code:: - - User.pick(:age) - # => 21 - -This method does not apply a sort to the documents, so it will not necessarily -return the values from the first document. - -The ``pick`` method accepts the dot notation and field aliases. It also -allows for picking localized fields. - - -``find`` delegates to ``Enumerable#find`` when given a block ------------------------------------------------------------- - -When given a block, without ``_id`` arguments, ``find`` delegates to -``Enumerable#find``. Consider the following model: - -.. code:: - - class Band - include Mongoid::Document - field :name, type: String - end - - Band.create!(name: "Depeche Mode") - Band.create!(name: "The Rolling Stones") - -Calling ``find`` with a block returns the first document for which the block -returns ``true``: - -.. code:: - - Band.find do |b| - b.name == "Depeche Mode" - end - # => # - - -No Longer Persisting Documents with Invalid ``belongs_to`` Associations ------------------------------------------------------------------------ - -In Mongoid 8, if an invalid document is assigned to a ``belongs_to`` association, -and the base document is saved, if the ``belongs_to`` association had the -option ``optional: false`` or ``optional`` is unset and the global flag -``belongs_to_required_by_default`` is true, neither the document nor the -associated document will be persisted. For example, given the following -models: - -.. code:: - - class Parent - include Mongoid::Document - has_one :child - field :name - validates :name, presence: true - end - - class Child - include Mongoid::Document - - belongs_to :parent, autosave: true, validate: false, optional: false - end - - child = Child.new - parent = Parent.new - child.parent = parent # parent is invalid, it does not have a name - child.save - -In this case, both the child and the parent will not be persisted. - -.. note:: - If ``save!`` were called, a validation error would be raised. - -If optional is false, then the Child will be persisted with a parent_id, but the -parent will not be persisted: - -.. code:: - - child = Child.new - parent = Parent.new - child.parent = parent # parent is invalid, it does not have a name - child.save - - p Child.first - # => - p Parent.first - # => nil - -If you want the functionality of neither document being persisted in Mongoid 7 or 8 -and earlier, the ``validate: true`` option can be set on the association. If -you want the functionality of only the Child being persisted, the ``validate: -false`` option can be set on the association. - - -Update Local HABTM Association Correctly ----------------------------------------- - -In Mongoid 8, when pushing persisted elements to a HABTM association, the -association will now update correctly without requiring a reload. -For example: - -.. code:: - - class User - include Mongoid::Document - has_and_belongs_to_many :posts - end - - class Post - include Mongoid::Document - has_and_belongs_to_many :users - end - - user1 = User.create! - user2 = User.create! - - post = user1.posts.create! - - p post.users.length - # => 1 - - post.users << user2 - - p post.users.length - # => 1 in Mongoid 7, 2 in Mongoid 8 - - p post.reload.users.length - # => 2 - -As you can see from this example, after pushing ``user2`` to the users array, -Mongoid 8 correctly updates the number of elements without requiring a reload. - - -Repaired Storing Strings in BSON::Binary fields ------------------------------------------------ - -**Breaking change:** In Mongoid 8, storing a String in a field of type -``BSON::Binary`` will be stored in and returned from the database as a -``BSON::Binary``. Prior to Mongoid 8 it was stored and returned as a String: - -.. code:: - - class Registry - include Mongoid::Document - field :data, type: BSON::Binary - end - - registry = Registry.create!(data: "data!") - p registry.data - # => Mongoid 7: "data!" - # => Mongoid 8: - - registry = Registry.find(registry.id) - p registry.data - # => Mongoid 7: "data!" - # => Mongoid 8: - - -Removed ``Document#to_a`` Method --------------------------------- - -The previously deprecated ``Document#to_a`` method has been removed in -Mongoid 8. - - -Removed ``:drop_dups`` Option from Indexes ------------------------------------------- - -The ``:drop_dups`` option has been removed from the ``index`` macro. This option -was specific to MongoDB server 2.6 and earlier, which Mongoid no longer supports. - - -Removed ``Mongoid::Errors::EagerLoad`` Exception Class ------------------------------------------------------- - -The previously deprecated ``Mongoid::Errors::EagerLoad`` exception class -has been removed in Mongoid 8. It has not been used by Mongoid since -version 7.1.1 when eager loading for polymorphic ``belongs_to`` associations -was implemented. - - -Removed Deprecated Constants ----------------------------- - -Mongoid 8 removes the following deprecated constants that are not expected -to have been used outside of Mongoid: - -- ``Mongoid::Extensions::Date::EPOCH`` -- ``Mongoid::Extensions::Time::EPOCH`` -- ``Mongoid::Factory::TYPE`` - - -Removed ``Array#update_values`` and ``Hash#update_values`` methods ------------------------------------------------------------------- - -The previously deprecated ``Array#update_values`` and ``Hash#update_values`` -methods have been removed in Mongoid 8. - - -Deprecated the ``geoHaystack``, ``geoSearch`` Options ------------------------------------------------------ - -The ``geoHaystack`` and ``geoSearch`` options on indexes have been deprecated. - - -``:id_sort`` Option on ``#first/last`` Removed ----------------------------------------------- - -Support for the ``:id_sort`` option on the ``#first`` and ``#last`` options has -been dropped. These methods now only except a limit as a positional argument. - - -Mongoid::Criteria Cache Removed -------------------------------- - -Support for individually caching criteria objects has been dropped in Mongoid 8. - -In order to get caching functionality, enable the Mongoid Query Cache. See the -section on :ref:`Query Cache ` for more details. - -New Caching Behavior of ``_ids`` Methods ------------------------------------------------------ - -If you call an ``_ids`` method, such as ``member_ids``, on an -association previously loaded into memory, Mongoid 8.0 uses the in-memory collection to satisfy the query -instead of issuing a new query to the database. - -For example, the following code calls the ``member_ids`` method and uses the in-memory -collection to retrieve the ``id`` values. The ``id`` of the ``new_member`` is not included -in the output: - -.. code-block:: ruby - - ids = band.member_ids - # ... - - new_member = Member.create(band_id: band.id) - - # Prior to 8.0, the method output includes the newly-created member's id. - # Starting in 8.0, the output does not include the newly-created member's id. - p band.member_ids - -You can force an ``_ids`` method to issue a new database query -by resetting the association before calling ``_ids``, as shown -in the following code: - -.. code-block:: ruby - - band.members.reset - - # Queries the database rather than the in-memory collection - p band.member_ids - -You can also issue a new database query by reloading the parent record -and calling the ``_ids`` method, as shown in the following code: - -.. code-block:: ruby - - band.reload.member_ids \ No newline at end of file diff --git a/source/release-notes/mongoid-8.1.txt b/source/release-notes/mongoid-8.1.txt deleted file mode 100644 index 5c69df80..00000000 --- a/source/release-notes/mongoid-8.1.txt +++ /dev/null @@ -1,431 +0,0 @@ -.. _mongoid-8.1: - -*********** -Mongoid 8.1 -*********** - -.. default-domain:: mongodb - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -This page describes significant changes and improvements in Mongoid 8.1. -The complete list of releases is available `on GitHub -`_ and `in JIRA -`_; -please consult GitHub releases for detailed release notes and JIRA for -the complete list of issues fixed in each release, including bug fixes. - -Added ``load_async`` method on ``Criteria`` to asynchronously load documents ----------------------------------------------------------------------------- - -The new ``load_async`` method on ``Criteria`` allows :ref:`running database queries asynchronously `. - - -Added ``attribute_before_last_save``, ``saved_change_to_attribute``, ``saved_change_to_attribute?``, and ``will_save_change_to_attribute?`` methods ----------------------------------------------------------------------------------------------------------------------------------------------------- - -These new methods behave identically to corresponding methods -from ``ActiveRecord::AttributeMethods::Dirty``. The methods are particularly useful in -callbacks: - -.. code-block:: ruby - - class Person - include Mongoid::Document - - field :name, type: String - - before_save do - puts "attribute_was(:name): #{attribute_was(:name)}" - puts "attribute_before_last_save(:name): #{attribute_before_last_save(:name)}" - puts "will_save_change_to_attribute?(:name): #{will_save_change_to_attribute?(:name)}" - end - - after_save do - puts "attribute_was(:name): #{attribute_was(:name)}" - puts "attribute_before_last_save(:name): #{attribute_before_last_save(:name)}" - puts "saved_change_to_attribute(:name): #{saved_change_to_attribute(:name)}" - puts "attribute_changed?(:name): #{attribute_changed?(:name)}" - puts "saved_change_to_attribute?(:name): #{saved_change_to_attribute?(:name)}" - end - end - - person = Person.create(name: 'John') - # - # before_save - # - ## attribute_was(:name): nil - ## attribute_before_last_save(:name): nil - ## will_save_change_to_attribute?(:name): true - # - # after_save - # - ## attribute_was(:name): John => New value - ## attribute_before_last_save(:name): nil => Value before save - ## saved_change_to_attribute(:name): [nil, "John"] => Both values - ## attribute_changed?(:name): false - ## saved_change_to_attribute?(:name): true => Correctly indicates that the change for :name was saved - - person.name = 'Jane' - person.save - # - # before_save - # - ## attribute_was(:name): John => attribute_was not look back before the last save - ## attribute_before_last_save(:name): nil => value before the last save - ## will_save_change_to_attribute?(:name): true - # - # after_save - # - ## attribute_was(:name): Jane => New value - ## attribute_before_last_save(:name): John => Value before save - ## saved_change_to_attribute(:name): ["John", "Jane"] => Both values - ## attribute_changed?(:name): false - ## saved_change_to_attribute?(:name): true => Correctly indicates that the change for :name was saved - -For all of the new methods there are also shorter forms created dynamically, e.g. -``attribute_before_last_save(:name)`` is equivalent to ``name_before_last_save``, -``saved_change_to_attribute(:name)`` is equivalent to ``saved_change_to_name``, -``saved_change_to_attribute?(:name)`` is equivalent to ``saved_change_to_name?``, -and ``will_save_change_to_attribute?(:name)`` is equivalent to ``will_save_change_to_name?``. - - -Deprecated ``use_activesupport_time_zone`` config option --------------------------------------------------------- - -The config option ``use_activesupport_time_zone`` has been deprecated. -Beginning in Mongoid 9.0, it will be ignored and always behave as true. -Since ``use_activesupport_time_zone`` currently defaults to true, it is -safe to remove from your config file at this time. - - -Configuration DSL No Longer Requires an Argument to its Block -------------------------------------------------------------- - -It is now possible to use ``Mongoid.configure`` without -providing an argument to its block: - -.. code-block:: ruby - - Mongoid.configure do - connect_to("mongoid_test") - - # Use config method when assigning variables - config.preload_models = true - -Note that ``configure`` will continue to support a block argument. -The following is equivalent to the above: - -.. code-block:: ruby - - Mongoid.configure do |config| - config.connect_to("mongoid_test") - - config.preload_models = true - - -Added ``Mongoid::Criteria`` finder methods ------------------------------------------- - -Mongoid 8.1 implements several finder methods on ``Mongoid::Criteria``: - -- ``first!`` -- ``last!`` -- ``second/second!`` -- ``third/third!`` -- ``fourth/fourth!`` -- ``fifth/fifth!`` -- ``second_to_last/second_to_last!`` -- ``third_to_last/third_to_last!`` - -When no documents are found, methods without a bang (!) return nil, and methods -with a bang (!) raise an error: - -.. code:: ruby - - Band.none.first - # => nil - - Band.none.first! - # => raise Mongoid::Errors::DocumentNotFound - - -Added ``:touch`` option to ``#save`` ------------------------------------- - -Support for the ``:touch`` option has been added to the ``#save`` and ``#save!`` -methods. When this option is false, the ``updated_at`` field on the saved -document and all of it's embedded documents will not be updated with the -current time. When this option is true or unset, the ``updated_at`` field will -be updated with the current time. - -If the document being saved is a new document (i.e. it has not yet been -persisted to the database), then the ``:touch`` option will be ignored, and the -``updated_at`` (and ``created_at``) fields will be updated with the current -time. - - -Added Version Based Default Configuration ------------------------------------------ - -Mongoid 8.1 has added the ability to set the default configurations for a -specific version: - -.. code:: ruby - - Mongoid.configure do |config| - config.load_defaults 8.0 - end - -This is helpful for upgrading between versions. See the section on -:ref:`Version Based Default Configuration ` for more details on -how to use this feature to make upgrading between Mongoid versions easier. - - -Added ``:present`` option to localized fields ---------------------------------------------- - -The ``:present`` option was added to localized fields for removing blank values -from the ``_translations`` hash: - -.. code-block:: ruby - - class Product - include Mongoid::Document - field :description, localize: :present - end - -See the section on :ref:`Localize :present Field Option ` for -more details on how these are used. - - -Added ``:to`` and ``:from`` options to ``attribute_changed?`` -------------------------------------------------------------- - -Mongoid 8.1 adds the ``:to`` and ``:from`` options on the ``attribute_changed?`` -method. These options can be used to inquire whether the attribute has been changed -to or from a certain value: - -.. code: - - class Person - include Mongoid::Document - field :name, type: String - end - - person = Person.create!(name: "Trout") - person.name = "Ohtani" - - person.name_changed? - # => true - person.name_changed?(from: "Trout") - # => true - person.name_changed?(to: "Ohtani") - # => true - person.name_changed?(from: "Trout", to: "Ohtani") - # => true - person.name_changed?(from: "Trout", to: "Fletcher") - # => false - - -Allowed ``store_in`` to be called on subclasses ------------------------------------------------ - -Starting in Mongoid 8.1, subclasses can now specify which collection its -documents should be stored in using the ``store_in`` macro: - -.. 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 - -Previously, an error was raised if this was done. See the section on -:ref:`Inheritance Persistence Context ` -for more details. - - -Added ``readonly!`` method and ``legacy_readonly`` feature flag ---------------------------------------------------------------- - -Mongoid 8.1 changes the meaning of read-only documents. In Mongoid 8.1 with -this feature flag turned off (``false``), a document becomes read-only when calling the -``readonly!`` method: - -.. code:: ruby - - band = Band.first - band.readonly? # => false - band.readonly! - band.readonly? # => true - band.name = "The Rolling Stones" - band.save # => raises ReadonlyDocument error - -With this feature flag turned off, a ``ReadonlyDocument`` error will be -raised when destroying or deleting, as well as when saving or updating. - -Prior to Mongoid 8.1 and in 8.1 with the ``legacy_readonly`` feature flag -turned on (``true``), documents become read-only when they are projected (i.e. using -``#only`` or ``#without``). - -.. 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 - -Note that with this feature flag on, a ``ReadonlyDocument`` error will only be -raised when destroying or deleting, and not on saving or updating. See the -section on :ref:`Read-only Documents ` for more details. - - -Added method parameters to ``#exists?`` ---------------------------------------- - -Mongoid 8.1 introduces method paramters to the ``Contextual#exists?`` method. -An _id, a hash of conditions, or ``false``/``nil`` can now be included: - -.. code:: ruby - - Band.exists? - Band.exists?(name: "The Rolling Stones") - Band.exists?(BSON::ObjectId('6320d96a3282a48cfce9e72c')) - Band.exists?(false) # always false - Band.exists?(nil) # always false - - -Added ``:replace`` option to ``#upsert`` ----------------------------------------- - -Mongoid 8.1 adds the ``:replace`` option to the ``#upsert`` method. This option -is ``false`` by default. - -In Mongoid 8 and earlier, and in Mongoid 8.1 when passing ``replace: true`` -(the default) the upserted document will overwrite the current document in the -database if it exists. Consider the following example: - -.. code:: ruby - - existing = Player.create!(name: "Juan Soto", age: 23, team: "WAS") - - player = Player.new(name: "Juan Soto", team: "SD") - player.id = existing.id - player.upsert # :replace defaults to true in 8.1 - - p Player.find(existing.id) - # => - -As you can see, the value for the ``:age`` field was dropped, because the -upsert replaced the entire document instead of just updating it. If we take the -same example and set ``:replace`` to ``false``, however: - -.. code:: ruby - - player.upsert(replace: false) - - p Player.find(existing.id) - # => - -This time, the value for the ``:age`` field is maintained. - -.. note:: - - The default for the ``:replace`` option will be changed to ``false`` in - Mongoid 9.0, therefore it is recommended to explicitly specify this option - while using ``#upsert`` in 8.1 for easier upgradability. - - -Allow Hash Assignment to ``embedded_in`` ----------------------------------------- - -Mongoid 8.1 allows the assignment of a hash to an ``embedded_in`` association. -On assignment, the hash will be coerced into a document of the class of the -association that it is being assigned to. This functionality already exists -for ``embeds_one`` and ``embeds_many`` associations. Consider the following -example: - -.. code:: ruby - - class Band - include Mongoid::Document - field :name, type: String - embeds_many :albums - end - - class Album - include Mongoid::Document - embedded_in :band - end - - album = Album.new - album.band = { name: "Death Cab For Cutie" } - p album.band - # => - -See the section on :ref:`Hash Assignment on Embedded Associations ` -for more details - - -Added ``none_of`` Query Method ------------------------------- - -With the addition of ``none_of``, Mongoid 8.1 allows queries to exclude -conditions in bulk. The emitted query will encapsulate the specified -criteria in a ``$nor`` operation. For example: - -.. code:: ruby - - class Building - include Mongoid::Document - field :city, type: String - field :height, type: Integer - field :purpose, type: String - field :occupancy, type: Integer - end - - Building.where(city: 'Portland'). - none_of(:height.lt => 100, - :purpose => 'apartment', - :occupancy.gt => 2500) - -This would query all buildings in Portland, excluding apartments, buildings less than -100 units tall, and buildings with an occupancy greater than 2500 people. - - -Added ``Mongoid::Config.immutable_ids`` ---------------------------------------- - -Coming in Mongoid 9.0, the ``_id`` field will be immutable in both top-level -and embedded documents. This addresses some inconsistency in how mutations -to the ``_id`` field are treated currently. To prepare for this potentially -breaking change, the ``Mongoid::Config.immutable_ids`` flag has been added. It -defaults to ``false``, preserving the existing behavior, but you may set it to -``true`` to prepare your apps for Mongoid 9.0. When this is set to ``true``, -attempts to mutate the ``_id`` of a document will raise an exception. - -.. code:: ruby - - # The default in Mongoid 8.1 - Mongoid::Config.immutable_ids = false - - # The default in Mongoid 9.0 - Mongoid::Config.immutable_ids = true