Skip to content

Commit

Permalink
MONGOID-5293 Add Rails-style defaults & config.load_defaults (#5405)
Browse files Browse the repository at this point in the history
* MONGOID-5293 add skeleton

* MONGOID-5293 add load_defaults method to config

* MONGOID-5293 comments

* MONGOID-5293 add docs and release notes
  • Loading branch information
Neilshweky authored Jul 25, 2022
1 parent 346feef commit 4d757e5
Show file tree
Hide file tree
Showing 6 changed files with 270 additions and 0 deletions.
58 changes: 58 additions & 0 deletions docs/reference/configuration.txt
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,64 @@ for details on driver options.
# methods. (default: false, driver version: 2.18.0+)
#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 <OLD VERSION>
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`` can be changed to take in the *new*
version, and all of the changed feature flags can be removed. For example, say
we're upgrading from 7.5 to 8.0. Between these two versions, only two feature
flags were added: ``legacy_attributes`` and ``map_big_decimal_to_decimal128``.
Before upgrading to Mongoid 8, the following line can be added:

.. code:: ruby

Mongoid.configure do |config|
config.load_defaults 7.5
end

Now, after upgrading, those two feature flags will default to their 7.5
functionality (``legacy_attributes: true, map_big_decimal_to_decimal128: false``).
Now you can set these feature flags one-by-one and flip them 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

It is advised to do these one at a time, so I have left 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
=================

Expand Down
1 change: 1 addition & 0 deletions docs/release-notes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Release Notes
.. toctree::
:titlesonly:

release-notes/mongoid-8.1
release-notes/mongoid-8.0
release-notes/mongoid-7.5
release-notes/mongoid-7.4
Expand Down
17 changes: 17 additions & 0 deletions docs/release-notes/mongoid-8.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,20 @@ 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 <load-defaults>` for more details on
how to use this feature to make upgrading between Mongoid versions easier.
2 changes: 2 additions & 0 deletions lib/mongoid/config.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true

require "mongoid/config/defaults"
require "mongoid/config/environment"
require "mongoid/config/options"
require "mongoid/config/validators"
Expand All @@ -11,6 +12,7 @@ module Mongoid
module Config
extend Forwardable
extend Options
extend Defaults
extend self

def_delegators ::Mongoid, :logger, :logger=
Expand Down
59 changes: 59 additions & 0 deletions lib/mongoid/config/defaults.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# frozen_string_literal: true

module Mongoid
module Config

# Encapsulates logic for loading defaults.
module Defaults

# Load the defaults for the feature flags in the given Mongoid version.
# Note that this method will load the *new* functionality introduced in
# the given Mongoid version.
#
# @param [ String | Float ] The version number as X.y.
#
# raises [ ArgumentError ] if an invalid version is given.
def load_defaults(version)
# Note that for 7.x, since all of the feature flag defaults have been
# flipped to the new functionality, all of the settings for those
# versions are to give old functionality. Because of this, it is
# possible to recurse to later version to get all of the options to
# turn off. Note that this won't be true when adding feature flags to
# 8.1, since the default will be the old functionality until the next
# major version is released. More likely, the recursion will have to go
# in the other direction (towards earlier versions).

case version.to_s
when "7.3"
# flags introduced in 7.4 - old functionality
self.broken_aggregables = true
self.broken_alias_handling = true
self.broken_and = true
self.broken_scoping = true
self.broken_updates = true
self.compare_time_by_ms = false
self.legacy_pluck_distinct = true
self.legacy_triple_equals = true
self.object_id_as_json_oid = true

load_defaults "7.4"
when "7.4"
# flags introduced in 7.5 - old functionality
self.overwrite_chained_operators = true

load_defaults "7.5"
when "7.5"
# flags introduced in 8.0 - old functionality
self.legacy_attributes = true
self.map_big_decimal_to_decimal128 = false
when "8.0"
# All flag defaults currently reflect 8.0 behavior.
when "8.1"
# All flag defaults currently reflect 8.1 behavior.
else
raise ArgumentError, "Unknown version: #{version}"
end
end
end
end
end
133 changes: 133 additions & 0 deletions spec/mongoid/config/defaults_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# frozen_string_literal: true

require "spec_helper"

describe Mongoid::Config::Defaults do

let(:config) do
Mongoid::Config
end

describe ".load_defaults" do

shared_examples "turns off 7.4 flags" do
it "turns off the 7.4 flags" do
expect(Mongoid.broken_aggregables).to be true
expect(Mongoid.broken_alias_handling).to be true
expect(Mongoid.broken_and).to be true
expect(Mongoid.broken_scoping).to be true
expect(Mongoid.broken_updates).to be true
expect(Mongoid.compare_time_by_ms).to be false
expect(Mongoid.legacy_pluck_distinct).to be true
expect(Mongoid.legacy_triple_equals).to be true
expect(Mongoid.object_id_as_json_oid).to be true
end
end

shared_examples "turns on 7.4 flags" do
it "turns on the 7.4 flags" do
expect(Mongoid.broken_aggregables).to be false
expect(Mongoid.broken_alias_handling).to be false
expect(Mongoid.broken_and).to be false
expect(Mongoid.broken_scoping).to be false
expect(Mongoid.broken_updates).to be false
expect(Mongoid.compare_time_by_ms).to be true
expect(Mongoid.legacy_pluck_distinct).to be false
expect(Mongoid.legacy_triple_equals).to be false
expect(Mongoid.object_id_as_json_oid).to be false
end
end

shared_examples "turns off 7.5 flags" do
it "turns off the 7.5 flags" do
expect(Mongoid.overwrite_chained_operators).to be true
end
end

shared_examples "turns on 7.5 flags" do
it "turns on the 7.5 flags" do
expect(Mongoid.overwrite_chained_operators).to be false
end
end

shared_examples "turns off 8.0 flags" do
it "turns off the 8.0 flags" do
expect(Mongoid.legacy_attributes).to be true
expect(Mongoid.map_big_decimal_to_decimal128).to be false
end
end

shared_examples "turns on 8.0 flags" do
it "turns on the 8.0 flags" do
expect(Mongoid.legacy_attributes).to be false
expect(Mongoid.map_big_decimal_to_decimal128).to be true
end
end

context "when giving a valid version" do

before do
config.load_defaults(version)
end

after do
Mongoid::Config.reset
end

context "when the given version is 7.3" do

let(:version) { 7.3 }

it_behaves_like "turns off 7.4 flags"
it_behaves_like "turns off 7.5 flags"
it_behaves_like "turns off 8.0 flags"
end

context "when the given version is 7.4" do

let(:version) { 7.4 }

it_behaves_like "turns on 7.4 flags"
it_behaves_like "turns off 7.5 flags"
it_behaves_like "turns off 8.0 flags"
end

context "when the given version is 7.5" do

let(:version) { 7.5 }

it_behaves_like "turns on 7.4 flags"
it_behaves_like "turns on 7.5 flags"
it_behaves_like "turns off 8.0 flags"
end

context "when the given version is 8.0" do

let(:version) { 8.0 }

it_behaves_like "turns on 7.4 flags"
it_behaves_like "turns on 7.5 flags"
it_behaves_like "turns on 8.0 flags"
end

context "when the given version is 8.1" do

let(:version) { 8.0 }

it_behaves_like "turns on 7.4 flags"
it_behaves_like "turns on 7.5 flags"
it_behaves_like "turns on 8.0 flags"
end
end

context "when given version an invalid version" do
let(:version) { 4.2 }

it "raises an error" do
expect do
config.load_defaults(version)
end.to raise_error(ArgumentError, /Unknown version: 4.2/)
end
end
end
end

0 comments on commit 4d757e5

Please sign in to comment.