*********** 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 ``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?``. 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.