mongoid 8.0.3 → 8.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/lib/config/locales/en.yml +46 -14
- data/lib/mongoid/association/accessors.rb +2 -2
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +23 -21
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +5 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/proxy.rb +7 -3
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +104 -4
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +101 -0
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +233 -33
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +373 -113
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
- data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
- data/lib/mongoid/criteria/translator.rb +45 -0
- data/lib/mongoid/criteria.rb +7 -5
- data/lib/mongoid/deprecable.rb +1 -1
- data/lib/mongoid/document.rb +50 -13
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -1
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/factory.rb +21 -8
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +69 -13
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +7 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/matcher.rb +21 -6
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/shardable.rb +35 -11
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/threaded.rb +30 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/macros.rb +5 -5
- data/lib/mongoid/validatable.rb +4 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +17 -1
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -2
- data/spec/integration/callbacks_models.rb +37 -0
- data/spec/integration/callbacks_spec.rb +134 -0
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +57 -57
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +148 -224
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +111 -164
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +5 -8
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -18
- data/spec/mongoid/contextual/memory_spec.rb +332 -76
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +995 -36
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +3 -11
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -69
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
- data/spec/mongoid/criteria/translator_spec.rb +132 -0
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -9
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -34
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +15 -3
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -4
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +9 -30
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +153 -61
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +35 -9
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/spec_helper.rb +5 -0
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/cover.rb +10 -0
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +700 -656
- metadata.gz.sig +0 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
|
@@ -27,11 +27,11 @@ describe Mongoid::Shardable do
|
|
|
27
27
|
context 'when full syntax is used' do
|
|
28
28
|
context 'with symbol value' do
|
|
29
29
|
it 'sets shard key fields to symbol value' do
|
|
30
|
-
SmProducer.shard_key_fields.
|
|
30
|
+
expect(SmProducer.shard_key_fields).to be == %i(age gender)
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
it 'sets shard config' do
|
|
34
|
-
SmProducer.shard_config.
|
|
34
|
+
expect(SmProducer.shard_config).to be == {
|
|
35
35
|
key: {age: 1, gender: 'hashed'},
|
|
36
36
|
options: {
|
|
37
37
|
unique: true,
|
|
@@ -41,37 +41,37 @@ describe Mongoid::Shardable do
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
it 'keeps hashed as string' do
|
|
44
|
-
SmProducer.shard_config[:key][:gender].
|
|
44
|
+
expect(SmProducer.shard_config[:key][:gender]).to be == 'hashed'
|
|
45
45
|
end
|
|
46
46
|
end
|
|
47
47
|
|
|
48
48
|
context 'with string value' do
|
|
49
49
|
it 'sets shard key fields to symbol value' do
|
|
50
|
-
SmActor.shard_key_fields.
|
|
50
|
+
expect(SmActor.shard_key_fields).to be == %i(age gender hello)
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
it 'sets shard config' do
|
|
54
|
-
SmActor.shard_config.
|
|
54
|
+
expect(SmActor.shard_config).to be == {
|
|
55
55
|
key: {age: 1, gender: 'hashed', hello: 'hashed'},
|
|
56
56
|
options: {},
|
|
57
57
|
}
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
it 'sets hashed to string' do
|
|
61
|
-
SmActor.shard_config[:key][:gender].
|
|
61
|
+
expect(SmActor.shard_config[:key][:gender]).to be == 'hashed'
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
context 'when passed association name' do
|
|
66
66
|
it 'uses foreign key as shard key in shard config' do
|
|
67
|
-
SmDriver.shard_config.
|
|
67
|
+
expect(SmDriver.shard_config).to be == {
|
|
68
68
|
key: {age: 1, agency_id: 'hashed'},
|
|
69
69
|
options: {},
|
|
70
70
|
}
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
it 'uses foreign key as shard key in shard key fields' do
|
|
74
|
-
SmDriver.shard_key_fields.
|
|
74
|
+
expect(SmDriver.shard_key_fields).to be == %i(age agency_id)
|
|
75
75
|
end
|
|
76
76
|
end
|
|
77
77
|
end
|
|
@@ -79,26 +79,26 @@ describe Mongoid::Shardable do
|
|
|
79
79
|
context 'when shorthand syntax is used' do
|
|
80
80
|
context 'with symbol value' do
|
|
81
81
|
it 'sets shard key fields to symbol value' do
|
|
82
|
-
SmMovie.shard_key_fields.
|
|
82
|
+
expect(SmMovie.shard_key_fields).to be == %i(year)
|
|
83
83
|
end
|
|
84
84
|
end
|
|
85
85
|
|
|
86
86
|
context 'with string value' do
|
|
87
87
|
it 'sets shard key fields to symbol value' do
|
|
88
|
-
SmTrailer.shard_key_fields.
|
|
88
|
+
expect(SmTrailer.shard_key_fields).to be == %i(year)
|
|
89
89
|
end
|
|
90
90
|
end
|
|
91
91
|
|
|
92
92
|
context 'when passed association name' do
|
|
93
93
|
it 'uses foreign key as shard key in shard config' do
|
|
94
|
-
SmDirector.shard_config.
|
|
94
|
+
expect(SmDirector.shard_config).to be == {
|
|
95
95
|
key: {agency_id: 1},
|
|
96
96
|
options: {},
|
|
97
97
|
}
|
|
98
98
|
end
|
|
99
99
|
|
|
100
100
|
it 'uses foreign key as shard key in shard key fields' do
|
|
101
|
-
SmDirector.shard_key_fields.
|
|
101
|
+
expect(SmDirector.shard_key_fields).to be == %i(agency_id)
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
end
|
|
@@ -106,41 +106,80 @@ describe Mongoid::Shardable do
|
|
|
106
106
|
|
|
107
107
|
describe '#shard_key_selector' do
|
|
108
108
|
subject { instance.shard_key_selector }
|
|
109
|
-
|
|
110
|
-
|
|
109
|
+
|
|
110
|
+
context 'when key is an immediate attribute' do
|
|
111
|
+
let(:klass) { Band }
|
|
112
|
+
let(:value) { 'a-brand-name' }
|
|
111
113
|
|
|
112
|
-
|
|
114
|
+
before { klass.shard_key(:name) }
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
context 'when record is new' do
|
|
117
|
+
let(:instance) { klass.new(name: value) }
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
it { is_expected.to eq({ 'name' => value }) }
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
context 'changing shard key value' do
|
|
122
|
+
let(:new_value) { 'a-new-value' }
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
+
before do
|
|
125
|
+
instance.name = new_value
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
it { is_expected.to eq({ 'name' => new_value }) }
|
|
124
129
|
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
context 'when record is persisted' do
|
|
133
|
+
let(:instance) { klass.create!(name: value) }
|
|
125
134
|
|
|
126
|
-
it { is_expected.to eq({ 'name' =>
|
|
135
|
+
it { is_expected.to eq({ 'name' => value }) }
|
|
136
|
+
|
|
137
|
+
context 'changing shard key value' do
|
|
138
|
+
let(:new_value) { 'a-new-value' }
|
|
139
|
+
|
|
140
|
+
before do
|
|
141
|
+
instance.name = new_value
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
it { is_expected.to eq({ 'name' => new_value }) }
|
|
145
|
+
end
|
|
127
146
|
end
|
|
128
147
|
end
|
|
129
148
|
|
|
130
|
-
context 'when
|
|
131
|
-
let(:
|
|
149
|
+
context 'when key is an embedded attribute' do
|
|
150
|
+
let(:klass) { SmReview }
|
|
151
|
+
let(:value) { 'Arthur Conan Doyle' }
|
|
152
|
+
let(:key) { 'author.name' }
|
|
132
153
|
|
|
133
|
-
|
|
154
|
+
context 'when record is new' do
|
|
155
|
+
let(:instance) { klass.new(author: { name: value }) }
|
|
134
156
|
|
|
135
|
-
|
|
136
|
-
let(:new_value) { 'a-new-value' }
|
|
157
|
+
it { is_expected.to eq({ key => value }) }
|
|
137
158
|
|
|
138
|
-
|
|
139
|
-
|
|
159
|
+
context 'changing shard key value' do
|
|
160
|
+
let(:new_value) { 'Jules Verne' }
|
|
161
|
+
|
|
162
|
+
before do
|
|
163
|
+
instance.author.name = new_value
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it { is_expected.to eq({ key => new_value }) }
|
|
140
167
|
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
context 'when record is persisted' do
|
|
171
|
+
let(:instance) { klass.create!(author: { name: value }) }
|
|
172
|
+
|
|
173
|
+
it { is_expected.to eq({ key => value }) }
|
|
174
|
+
|
|
175
|
+
context 'changing shard key value' do
|
|
176
|
+
let(:new_value) { 'Jules Verne' }
|
|
141
177
|
|
|
142
|
-
|
|
143
|
-
|
|
178
|
+
before do
|
|
179
|
+
instance.author.name = new_value
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it { is_expected.to eq({ 'author.name' => new_value }) }
|
|
144
183
|
end
|
|
145
184
|
end
|
|
146
185
|
end
|
|
@@ -148,56 +187,109 @@ describe Mongoid::Shardable do
|
|
|
148
187
|
|
|
149
188
|
describe '#shard_key_selector_in_db' do
|
|
150
189
|
subject { instance.shard_key_selector_in_db }
|
|
151
|
-
let(:klass) { Band }
|
|
152
|
-
let(:value) { 'a-brand-name' }
|
|
153
190
|
|
|
154
|
-
|
|
191
|
+
context 'when key is an immediate attribute' do
|
|
192
|
+
let(:klass) { Band }
|
|
193
|
+
let(:value) { 'a-brand-name' }
|
|
155
194
|
|
|
156
|
-
|
|
157
|
-
let(:instance) { klass.new(name: value) }
|
|
195
|
+
before { klass.shard_key(:name) }
|
|
158
196
|
|
|
159
|
-
|
|
197
|
+
context 'when record is new' do
|
|
198
|
+
let(:instance) { klass.new(name: value) }
|
|
160
199
|
|
|
161
|
-
|
|
162
|
-
let(:new_value) { 'a-new-value' }
|
|
200
|
+
it { is_expected.to eq({ 'name' => value }) }
|
|
163
201
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
202
|
+
context 'changing shard key value' do
|
|
203
|
+
let(:new_value) { 'a-new-value' }
|
|
204
|
+
|
|
205
|
+
before do
|
|
206
|
+
instance.name = new_value
|
|
207
|
+
end
|
|
167
208
|
|
|
168
|
-
|
|
169
|
-
subject.should == { 'name' => new_value }
|
|
209
|
+
it { is_expected.to eq({ 'name' => new_value }) }
|
|
170
210
|
end
|
|
171
211
|
end
|
|
172
|
-
end
|
|
173
212
|
|
|
174
|
-
|
|
175
|
-
|
|
213
|
+
context 'when record is persisted' do
|
|
214
|
+
let(:instance) { klass.create!(name: value) }
|
|
215
|
+
|
|
216
|
+
it { is_expected.to eq({ 'name' => value }) }
|
|
217
|
+
|
|
218
|
+
context 'changing shard key value' do
|
|
219
|
+
let(:new_value) { 'a-new-value' }
|
|
176
220
|
|
|
177
|
-
|
|
221
|
+
before do
|
|
222
|
+
instance.name = new_value
|
|
223
|
+
end
|
|
178
224
|
|
|
179
|
-
|
|
180
|
-
|
|
225
|
+
it { is_expected.to eq({ 'name' => value }) }
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
|
|
229
|
+
context "when record is not found" do
|
|
230
|
+
let!(:instance) { klass.create!(name: value) }
|
|
181
231
|
|
|
182
232
|
before do
|
|
183
|
-
instance.
|
|
233
|
+
instance.destroy
|
|
184
234
|
end
|
|
185
235
|
|
|
186
|
-
it
|
|
236
|
+
it "raises a DocumentNotFound error with the shard key in the description on reload" do
|
|
237
|
+
expect do
|
|
238
|
+
instance.reload
|
|
239
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class Band with id #{instance.id.to_s} and shard key name: a-brand-name./)
|
|
240
|
+
end
|
|
187
241
|
end
|
|
188
242
|
end
|
|
189
243
|
|
|
190
|
-
context
|
|
191
|
-
let
|
|
244
|
+
context 'when key is an embedded attribute' do
|
|
245
|
+
let(:klass) { SmReview }
|
|
246
|
+
let(:value) { 'Arthur Conan Doyle' }
|
|
247
|
+
let(:key) { 'author.name' }
|
|
248
|
+
|
|
249
|
+
context 'when record is new' do
|
|
250
|
+
let(:instance) { klass.new(author: { name: value }) }
|
|
251
|
+
|
|
252
|
+
it { is_expected.to eq({ key => value }) }
|
|
192
253
|
|
|
193
|
-
|
|
194
|
-
|
|
254
|
+
context 'changing shard key value' do
|
|
255
|
+
let(:new_value) { 'Jules Verne' }
|
|
256
|
+
|
|
257
|
+
before do
|
|
258
|
+
instance.author.name = new_value
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it { is_expected.to eq({ key => new_value }) }
|
|
262
|
+
end
|
|
195
263
|
end
|
|
196
264
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
265
|
+
context 'when record is persisted' do
|
|
266
|
+
let(:instance) { klass.create!(author: { name: value }) }
|
|
267
|
+
|
|
268
|
+
it { is_expected.to eq({ key => value }) }
|
|
269
|
+
|
|
270
|
+
context 'changing shard key value' do
|
|
271
|
+
let(:new_value) { 'Jules Verne' }
|
|
272
|
+
|
|
273
|
+
before do
|
|
274
|
+
instance.author.name = new_value
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
it { is_expected.to eq({ key => value }) }
|
|
278
|
+
end
|
|
279
|
+
|
|
280
|
+
context "when record is not found" do
|
|
281
|
+
let!(:instance) { klass.create!(author: { name: value }) }
|
|
282
|
+
|
|
283
|
+
before do
|
|
284
|
+
instance.destroy
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
it "raises a DocumentNotFound error with the shard key in the description on reload" do
|
|
288
|
+
expect do
|
|
289
|
+
instance.reload
|
|
290
|
+
end.to raise_error(Mongoid::Errors::DocumentNotFound, /Document not found for class SmReview with id #{instance.id.to_s} and shard key author.name: Arthur Conan Doyle./)
|
|
291
|
+
end
|
|
292
|
+
end
|
|
201
293
|
end
|
|
202
294
|
end
|
|
203
295
|
end
|
|
@@ -136,21 +136,135 @@ describe Mongoid::Stateful do
|
|
|
136
136
|
Band.new
|
|
137
137
|
end
|
|
138
138
|
|
|
139
|
-
context "when
|
|
139
|
+
context "when legacy_readonly is true" do
|
|
140
|
+
config_override :legacy_readonly, true
|
|
140
141
|
|
|
141
|
-
|
|
142
|
-
|
|
142
|
+
context "when the selected fields are set" do
|
|
143
|
+
|
|
144
|
+
before do
|
|
145
|
+
document.__selected_fields = { test: 1 }
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
it "returns true" do
|
|
149
|
+
expect(document).to be_readonly
|
|
150
|
+
end
|
|
143
151
|
end
|
|
144
152
|
|
|
145
|
-
|
|
146
|
-
|
|
153
|
+
context "when no readonly has been set" do
|
|
154
|
+
|
|
155
|
+
it "returns false" do
|
|
156
|
+
expect(document).to_not be_readonly
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
context "when the readonly! method is called" do
|
|
161
|
+
|
|
162
|
+
let(:op) do
|
|
163
|
+
document.readonly!
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
it "returns false" do
|
|
167
|
+
op
|
|
168
|
+
expect(document).to_not be_readonly
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
it "warns" do
|
|
172
|
+
expect(Mongoid::Warnings).to receive(:warn_legacy_readonly)
|
|
173
|
+
op
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
context "when overriding readonly?" do
|
|
178
|
+
|
|
179
|
+
let(:doc) { ReadonlyModel.create! }
|
|
180
|
+
|
|
181
|
+
before do
|
|
182
|
+
class ReadonlyModel
|
|
183
|
+
include Mongoid::Document
|
|
184
|
+
|
|
185
|
+
attr_accessor :locked
|
|
186
|
+
|
|
187
|
+
def readonly?
|
|
188
|
+
!!locked
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
after do
|
|
194
|
+
Object.send(:remove_const, :ReadonlyModel)
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
it "raises when readonly? is true" do
|
|
198
|
+
expect(doc.readonly?).to be false
|
|
199
|
+
doc.locked = true
|
|
200
|
+
expect(doc.readonly?).to be true
|
|
201
|
+
expect do
|
|
202
|
+
doc.destroy
|
|
203
|
+
end.to raise_error(Mongoid::Errors::ReadonlyDocument)
|
|
204
|
+
end
|
|
147
205
|
end
|
|
148
206
|
end
|
|
149
207
|
|
|
150
|
-
context "when
|
|
208
|
+
context "when legacy_readonly is false" do
|
|
209
|
+
config_override :legacy_readonly, false
|
|
151
210
|
|
|
152
|
-
|
|
153
|
-
|
|
211
|
+
context "when the selected fields are set" do
|
|
212
|
+
|
|
213
|
+
before do
|
|
214
|
+
document.__selected_fields = { test: 1 }
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
it "returns false" do
|
|
218
|
+
expect(document).to_not be_readonly
|
|
219
|
+
end
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
context "when the readonly! method is called" do
|
|
223
|
+
|
|
224
|
+
before do
|
|
225
|
+
document.readonly!
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
it "returns true" do
|
|
229
|
+
expect(document).to be_readonly
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context "when no readonly has been set" do
|
|
234
|
+
|
|
235
|
+
it "returns false" do
|
|
236
|
+
expect(document).to_not be_readonly
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
context "when overriding readonly?" do
|
|
241
|
+
|
|
242
|
+
let(:doc) { ReadonlyModel.new }
|
|
243
|
+
|
|
244
|
+
before do
|
|
245
|
+
class ReadonlyModel
|
|
246
|
+
include Mongoid::Document
|
|
247
|
+
|
|
248
|
+
attr_accessor :locked
|
|
249
|
+
|
|
250
|
+
def readonly?
|
|
251
|
+
!!locked
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
after do
|
|
257
|
+
Object.send(:remove_const, :ReadonlyModel)
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
it "raises when readonly? is true" do
|
|
261
|
+
expect(doc.readonly?).to be false
|
|
262
|
+
doc.locked = true
|
|
263
|
+
expect(doc.readonly?).to be true
|
|
264
|
+
expect do
|
|
265
|
+
doc.save!
|
|
266
|
+
end.to raise_error(Mongoid::Errors::ReadonlyDocument)
|
|
267
|
+
end
|
|
154
268
|
end
|
|
155
269
|
end
|
|
156
270
|
end
|
|
@@ -35,6 +35,22 @@ shared_context "rake task" do
|
|
|
35
35
|
task.invoke
|
|
36
36
|
end
|
|
37
37
|
end
|
|
38
|
+
|
|
39
|
+
shared_examples_for "create_collections" do
|
|
40
|
+
|
|
41
|
+
it "receives create_collections" do
|
|
42
|
+
expect(Mongoid::Tasks::Database).to receive(:create_collections)
|
|
43
|
+
task.invoke
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
shared_examples_for "force create_collections" do
|
|
48
|
+
|
|
49
|
+
it "receives create_collections" do
|
|
50
|
+
expect(Mongoid::Tasks::Database).to receive(:create_collections).with(force: true)
|
|
51
|
+
task.invoke
|
|
52
|
+
end
|
|
53
|
+
end
|
|
38
54
|
end
|
|
39
55
|
|
|
40
56
|
shared_context "rails rake task" do
|
|
@@ -99,6 +115,10 @@ describe "db:setup" do
|
|
|
99
115
|
expect(task.prerequisites).to include("mongoid:create_indexes")
|
|
100
116
|
end
|
|
101
117
|
|
|
118
|
+
it "calls db:mongoid:create_collections" do
|
|
119
|
+
expect(task.prerequisites).to include("mongoid:create_collections")
|
|
120
|
+
end
|
|
121
|
+
|
|
102
122
|
it "calls db:seed" do
|
|
103
123
|
expect(task.prerequisites).to include("db:seed")
|
|
104
124
|
end
|
|
@@ -113,6 +133,7 @@ describe "db:setup" do
|
|
|
113
133
|
|
|
114
134
|
it "works" do
|
|
115
135
|
expect(Mongoid::Tasks::Database).to receive(:create_indexes)
|
|
136
|
+
expect(Mongoid::Tasks::Database).to receive(:create_collections)
|
|
116
137
|
expect(Rails).to receive(:root).and_return(".")
|
|
117
138
|
expect(Rails).to receive(:application).and_return(application)
|
|
118
139
|
task.invoke
|
|
@@ -169,9 +190,14 @@ describe "db:test:prepare" do
|
|
|
169
190
|
expect(task.prerequisites).to include("mongoid:create_indexes")
|
|
170
191
|
end
|
|
171
192
|
|
|
193
|
+
it "calls mongoid:create_collections" do
|
|
194
|
+
expect(task.prerequisites).to include("mongoid:create_collections")
|
|
195
|
+
end
|
|
196
|
+
|
|
172
197
|
it "works" do
|
|
173
198
|
expect(Rails).to receive(:application).and_return(application)
|
|
174
199
|
expect(Mongoid::Tasks::Database).to receive(:create_indexes)
|
|
200
|
+
expect(Mongoid::Tasks::Database).to receive(:create_collections)
|
|
175
201
|
task.invoke
|
|
176
202
|
end
|
|
177
203
|
end
|
|
@@ -200,6 +226,54 @@ describe "db:mongoid:create_indexes" do
|
|
|
200
226
|
end
|
|
201
227
|
end
|
|
202
228
|
|
|
229
|
+
describe "db:mongoid:create_collections" do
|
|
230
|
+
include_context "rake task"
|
|
231
|
+
|
|
232
|
+
it_behaves_like "create_collections"
|
|
233
|
+
|
|
234
|
+
it "calls load_models" do
|
|
235
|
+
expect(task.prerequisites).to include("load_models")
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
it "calls environment" do
|
|
239
|
+
expect(task.prerequisites).to include("environment")
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
context "when using rails task" do
|
|
243
|
+
include_context "rails rake task"
|
|
244
|
+
|
|
245
|
+
before do
|
|
246
|
+
expect(Rails).to receive(:application).and_return(application)
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
it_behaves_like "create_collections"
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
|
|
253
|
+
describe "db:mongoid:create_collections:force" do
|
|
254
|
+
include_context "rake task"
|
|
255
|
+
|
|
256
|
+
it_behaves_like "force create_collections"
|
|
257
|
+
|
|
258
|
+
it "calls load_models" do
|
|
259
|
+
expect(task.prerequisites).to include("load_models")
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
it "calls environment" do
|
|
263
|
+
expect(task.prerequisites).to include("environment")
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
context "when using rails task" do
|
|
267
|
+
include_context "rails rake task"
|
|
268
|
+
|
|
269
|
+
before do
|
|
270
|
+
expect(Rails).to receive(:application).and_return(application)
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
it_behaves_like "force create_collections"
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
203
277
|
describe "db:mongoid:remove_undefined_indexes" do
|
|
204
278
|
include_context "rake task"
|
|
205
279
|
|