Skip to content

Commit 4d757e5

Browse files
authored
MONGOID-5293 Add Rails-style defaults & config.load_defaults (#5405)
* MONGOID-5293 add skeleton * MONGOID-5293 add load_defaults method to config * MONGOID-5293 comments * MONGOID-5293 add docs and release notes
1 parent 346feef commit 4d757e5

File tree

6 files changed

+270
-0
lines changed

6 files changed

+270
-0
lines changed

docs/reference/configuration.txt

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,64 @@ for details on driver options.
458458
# methods. (default: false, driver version: 2.18.0+)
459459
#validate_update_replace: false
460460

461+
462+
.. _load-defaults:
463+
464+
Version Based Defaults
465+
======================
466+
467+
Mongoid supports setting the configuration options to the defaults for specific
468+
versions. This is useful for upgrading to a new Mongoid version. When upgrading
469+
your Mongoid version, the following should be set on ``Mongoid::Config``:
470+
471+
.. code:: ruby
472+
473+
Mongoid.configure do |config|
474+
config.load_defaults <OLD VERSION>
475+
end
476+
477+
This way, when upgrading to a new version of Mongoid, your code will run with
478+
the configuration options from the previous version of Mongoid. Then,
479+
one-by-one, you can change the feature flags for the new version, and test that
480+
your code still acts as expected. Once all of the new feature flags have been
481+
accounted for, the call to ``load_defaults`` can be changed to take in the *new*
482+
version, and all of the changed feature flags can be removed. For example, say
483+
we're upgrading from 7.5 to 8.0. Between these two versions, only two feature
484+
flags were added: ``legacy_attributes`` and ``map_big_decimal_to_decimal128``.
485+
Before upgrading to Mongoid 8, the following line can be added:
486+
487+
.. code:: ruby
488+
489+
Mongoid.configure do |config|
490+
config.load_defaults 7.5
491+
end
492+
493+
Now, after upgrading, those two feature flags will default to their 7.5
494+
functionality (``legacy_attributes: true, map_big_decimal_to_decimal128: false``).
495+
Now you can set these feature flags one-by-one and flip them to their 8.0
496+
behavior:
497+
498+
.. code:: ruby
499+
500+
Mongoid.configure do |config|
501+
config.load_defaults 7.5
502+
config.legacy_attributes = false
503+
# config.map_big_decimal_to_decimal128 = true
504+
end
505+
506+
It is advised to do these one at a time, so I have left the second flag
507+
commented out. After verifying your code works as expected with the
508+
``legacy_attributes`` flag turned off, the ``map_big_decimal_to_decimal128``
509+
setting can be uncommented. Once that functionality is verified as well, both
510+
of those lines can be removed and the ``load_defaults`` replaced with:
511+
512+
.. code:: ruby
513+
514+
Mongoid.configure do |config|
515+
config.load_defaults 8.0
516+
end
517+
518+
461519
ERb Preprocessing
462520
=================
463521

docs/release-notes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Release Notes
99
.. toctree::
1010
:titlesonly:
1111

12+
release-notes/mongoid-8.1
1213
release-notes/mongoid-8.0
1314
release-notes/mongoid-7.5
1415
release-notes/mongoid-7.4

docs/release-notes/mongoid-8.1.txt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,20 @@ If the document being saved is a new document (i.e. it has not yet been
5757
persisted to the database), then the ``:touch`` option will be ignored, and the
5858
``updated_at`` (and ``created_at``) fields will be updated with the current
5959
time.
60+
61+
62+
Added Version Based Default Configuration
63+
-----------------------------------------
64+
65+
Mongoid 8.1 has added the ability to set the default configurations for a
66+
specific version:
67+
68+
.. code:: ruby
69+
70+
Mongoid.configure do |config|
71+
config.load_defaults 8.0
72+
end
73+
74+
This is helpful for upgrading between versions. See the section on
75+
:ref:`Version Based Default Configuration <load-defaults>` for more details on
76+
how to use this feature to make upgrading between Mongoid versions easier.

lib/mongoid/config.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# frozen_string_literal: true
22

3+
require "mongoid/config/defaults"
34
require "mongoid/config/environment"
45
require "mongoid/config/options"
56
require "mongoid/config/validators"
@@ -11,6 +12,7 @@ module Mongoid
1112
module Config
1213
extend Forwardable
1314
extend Options
15+
extend Defaults
1416
extend self
1517

1618
def_delegators ::Mongoid, :logger, :logger=

lib/mongoid/config/defaults.rb

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# frozen_string_literal: true
2+
3+
module Mongoid
4+
module Config
5+
6+
# Encapsulates logic for loading defaults.
7+
module Defaults
8+
9+
# Load the defaults for the feature flags in the given Mongoid version.
10+
# Note that this method will load the *new* functionality introduced in
11+
# the given Mongoid version.
12+
#
13+
# @param [ String | Float ] The version number as X.y.
14+
#
15+
# raises [ ArgumentError ] if an invalid version is given.
16+
def load_defaults(version)
17+
# Note that for 7.x, since all of the feature flag defaults have been
18+
# flipped to the new functionality, all of the settings for those
19+
# versions are to give old functionality. Because of this, it is
20+
# possible to recurse to later version to get all of the options to
21+
# turn off. Note that this won't be true when adding feature flags to
22+
# 8.1, since the default will be the old functionality until the next
23+
# major version is released. More likely, the recursion will have to go
24+
# in the other direction (towards earlier versions).
25+
26+
case version.to_s
27+
when "7.3"
28+
# flags introduced in 7.4 - old functionality
29+
self.broken_aggregables = true
30+
self.broken_alias_handling = true
31+
self.broken_and = true
32+
self.broken_scoping = true
33+
self.broken_updates = true
34+
self.compare_time_by_ms = false
35+
self.legacy_pluck_distinct = true
36+
self.legacy_triple_equals = true
37+
self.object_id_as_json_oid = true
38+
39+
load_defaults "7.4"
40+
when "7.4"
41+
# flags introduced in 7.5 - old functionality
42+
self.overwrite_chained_operators = true
43+
44+
load_defaults "7.5"
45+
when "7.5"
46+
# flags introduced in 8.0 - old functionality
47+
self.legacy_attributes = true
48+
self.map_big_decimal_to_decimal128 = false
49+
when "8.0"
50+
# All flag defaults currently reflect 8.0 behavior.
51+
when "8.1"
52+
# All flag defaults currently reflect 8.1 behavior.
53+
else
54+
raise ArgumentError, "Unknown version: #{version}"
55+
end
56+
end
57+
end
58+
end
59+
end

spec/mongoid/config/defaults_spec.rb

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# frozen_string_literal: true
2+
3+
require "spec_helper"
4+
5+
describe Mongoid::Config::Defaults do
6+
7+
let(:config) do
8+
Mongoid::Config
9+
end
10+
11+
describe ".load_defaults" do
12+
13+
shared_examples "turns off 7.4 flags" do
14+
it "turns off the 7.4 flags" do
15+
expect(Mongoid.broken_aggregables).to be true
16+
expect(Mongoid.broken_alias_handling).to be true
17+
expect(Mongoid.broken_and).to be true
18+
expect(Mongoid.broken_scoping).to be true
19+
expect(Mongoid.broken_updates).to be true
20+
expect(Mongoid.compare_time_by_ms).to be false
21+
expect(Mongoid.legacy_pluck_distinct).to be true
22+
expect(Mongoid.legacy_triple_equals).to be true
23+
expect(Mongoid.object_id_as_json_oid).to be true
24+
end
25+
end
26+
27+
shared_examples "turns on 7.4 flags" do
28+
it "turns on the 7.4 flags" do
29+
expect(Mongoid.broken_aggregables).to be false
30+
expect(Mongoid.broken_alias_handling).to be false
31+
expect(Mongoid.broken_and).to be false
32+
expect(Mongoid.broken_scoping).to be false
33+
expect(Mongoid.broken_updates).to be false
34+
expect(Mongoid.compare_time_by_ms).to be true
35+
expect(Mongoid.legacy_pluck_distinct).to be false
36+
expect(Mongoid.legacy_triple_equals).to be false
37+
expect(Mongoid.object_id_as_json_oid).to be false
38+
end
39+
end
40+
41+
shared_examples "turns off 7.5 flags" do
42+
it "turns off the 7.5 flags" do
43+
expect(Mongoid.overwrite_chained_operators).to be true
44+
end
45+
end
46+
47+
shared_examples "turns on 7.5 flags" do
48+
it "turns on the 7.5 flags" do
49+
expect(Mongoid.overwrite_chained_operators).to be false
50+
end
51+
end
52+
53+
shared_examples "turns off 8.0 flags" do
54+
it "turns off the 8.0 flags" do
55+
expect(Mongoid.legacy_attributes).to be true
56+
expect(Mongoid.map_big_decimal_to_decimal128).to be false
57+
end
58+
end
59+
60+
shared_examples "turns on 8.0 flags" do
61+
it "turns on the 8.0 flags" do
62+
expect(Mongoid.legacy_attributes).to be false
63+
expect(Mongoid.map_big_decimal_to_decimal128).to be true
64+
end
65+
end
66+
67+
context "when giving a valid version" do
68+
69+
before do
70+
config.load_defaults(version)
71+
end
72+
73+
after do
74+
Mongoid::Config.reset
75+
end
76+
77+
context "when the given version is 7.3" do
78+
79+
let(:version) { 7.3 }
80+
81+
it_behaves_like "turns off 7.4 flags"
82+
it_behaves_like "turns off 7.5 flags"
83+
it_behaves_like "turns off 8.0 flags"
84+
end
85+
86+
context "when the given version is 7.4" do
87+
88+
let(:version) { 7.4 }
89+
90+
it_behaves_like "turns on 7.4 flags"
91+
it_behaves_like "turns off 7.5 flags"
92+
it_behaves_like "turns off 8.0 flags"
93+
end
94+
95+
context "when the given version is 7.5" do
96+
97+
let(:version) { 7.5 }
98+
99+
it_behaves_like "turns on 7.4 flags"
100+
it_behaves_like "turns on 7.5 flags"
101+
it_behaves_like "turns off 8.0 flags"
102+
end
103+
104+
context "when the given version is 8.0" do
105+
106+
let(:version) { 8.0 }
107+
108+
it_behaves_like "turns on 7.4 flags"
109+
it_behaves_like "turns on 7.5 flags"
110+
it_behaves_like "turns on 8.0 flags"
111+
end
112+
113+
context "when the given version is 8.1" do
114+
115+
let(:version) { 8.0 }
116+
117+
it_behaves_like "turns on 7.4 flags"
118+
it_behaves_like "turns on 7.5 flags"
119+
it_behaves_like "turns on 8.0 flags"
120+
end
121+
end
122+
123+
context "when given version an invalid version" do
124+
let(:version) { 4.2 }
125+
126+
it "raises an error" do
127+
expect do
128+
config.load_defaults(version)
129+
end.to raise_error(ArgumentError, /Unknown version: 4.2/)
130+
end
131+
end
132+
end
133+
end

0 commit comments

Comments
 (0)