Navigation

Mongoid 8.0

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.

Ruby Version Support

Mongoid 8.0 removes support for JRuby.

Support for MongoDB 3.4 and Earlier Servers Dropped

Mongoid 8 requires MongoDB 3.6 or newer. Earlier server 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_pluck_distinct => false
  • :legacy_triple_equals => false
  • :map_big_decimal_to_decimal128 => true
  • :object_id_as_json_oid => false

Please refer to configuration option for the description and effects of each of these options.

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):

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):

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

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:

Band.any_of({name: 'Rolling Stone'}, {founded: 1990}).
  any_of({members: 2}, {last_tour: 1995})
# =>
# #<Mongoid::Criteria
#   selector: {"$or"=>[{"name"=>"Rolling Stone"}, {"founded"=>1990}],
#     "$and"=>[{"$or"=>[{"members"=>2}, {"last_tour"=>1995}]}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Band.any_of({name: 'Rolling Stone'}, {founded: 1990}).any_of({members: 2})
# =>
# #<Mongoid::Criteria
#   selector: {"$or"=>[{"name"=>"Rolling Stone"}, {"founded"=>1990}], "members"=>2}
#   options:  {}
#   class:    Band
#   embedded: false>

Mongoid 7 behavior:

Band.any_of({name: 'Rolling Stone'}, {founded: 1990}).
  any_of({members: 2}, {last_tour: 1995})
# =>
# #<Mongoid::Criteria
#   selector: {"$or"=>[{"name"=>"Rolling Stone"}, {"founded"=>1990},
#     {"members"=>2}, {"last_tour"=>1995}]}
#   options:  {}
#   class:    Band
#   embedded: false>

Band.any_of({name: 'Rolling Stone'}, {founded: 1990}).any_of({members: 2})
# =>
# #<Mongoid::Criteria
#   selector: {"$or"=>[{"name"=>"Rolling Stone"}, {"founded"=>1990}], "members"=>2}
#   options:  {}
#   class:    Band
#   embedded: false>

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.

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:

#<Cat _id: 60aef1652c97a617438dc9bb, age: 2>
2

Mongoid 7 output:

#<Cat _id: 60aef1652c97a617438dc9bb, age: 2>
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:

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

Removed Document#to_a method

The Document#to_a method has been removed in Mongoid 8.

←   Release Notes Mongoid 7.4  →