mongoid 5.4.0 → 6.4.8
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/README.md +3 -3
- data/Rakefile +26 -0
- data/lib/config/locales/en.yml +40 -0
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +5 -5
- data/lib/mongoid/attributes/readonly.rb +22 -0
- data/lib/mongoid/attributes.rb +22 -21
- data/lib/mongoid/cacheable.rb +36 -0
- data/lib/mongoid/changeable.rb +36 -0
- data/lib/mongoid/clients/options.rb +55 -250
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +2 -69
- data/lib/mongoid/clients.rb +10 -63
- data/lib/mongoid/composable.rb +29 -2
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +4 -4
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +9 -4
- data/lib/mongoid/contextual/mongo.rb +65 -30
- data/lib/mongoid/contextual/none.rb +12 -0
- data/lib/mongoid/copyable.rb +13 -6
- data/lib/mongoid/criteria/marshalable.rb +2 -2
- data/lib/mongoid/criteria/modifiable.rb +29 -3
- data/lib/mongoid/criteria/options.rb +25 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
- data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
- data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
- data/lib/mongoid/criteria/queryable/key.rb +103 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
- data/lib/mongoid/criteria/queryable/optional.rb +429 -0
- data/lib/mongoid/criteria/queryable/options.rb +153 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
- data/lib/mongoid/criteria/queryable/selector.rb +212 -0
- data/lib/mongoid/criteria/queryable/smash.rb +104 -0
- data/lib/mongoid/criteria/queryable.rb +87 -0
- data/lib/mongoid/criteria.rb +6 -2
- data/lib/mongoid/document.rb +34 -41
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
- data/lib/mongoid/errors/invalid_field.rb +2 -2
- data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
- data/lib/mongoid/errors/invalid_relation.rb +66 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/big_decimal.rb +17 -8
- data/lib/mongoid/extensions/date.rb +4 -1
- data/lib/mongoid/extensions/decimal128.rb +3 -3
- data/lib/mongoid/extensions/hash.rb +1 -0
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +6 -3
- data/lib/mongoid/extensions/time.rb +4 -1
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/factory.rb +2 -1
- data/lib/mongoid/fields/validators/macro.rb +18 -0
- data/lib/mongoid/findable.rb +2 -2
- data/lib/mongoid/indexable.rb +16 -14
- data/lib/mongoid/interceptable.rb +9 -22
- data/lib/mongoid/matchable/all.rb +2 -2
- data/lib/mongoid/matchable/and.rb +3 -3
- data/lib/mongoid/matchable/default.rb +2 -2
- data/lib/mongoid/matchable/elem_match.rb +28 -0
- data/lib/mongoid/matchable/exists.rb +2 -2
- data/lib/mongoid/matchable/gt.rb +4 -2
- data/lib/mongoid/matchable/gte.rb +4 -2
- data/lib/mongoid/matchable/in.rb +2 -2
- data/lib/mongoid/matchable/lt.rb +4 -2
- data/lib/mongoid/matchable/lte.rb +4 -2
- data/lib/mongoid/matchable/ne.rb +2 -2
- data/lib/mongoid/matchable/nin.rb +2 -2
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/matchable/or.rb +3 -3
- data/lib/mongoid/matchable/regexp.rb +3 -3
- data/lib/mongoid/matchable/size.rb +2 -2
- data/lib/mongoid/matchable.rb +16 -7
- data/lib/mongoid/persistable/creatable.rb +5 -3
- data/lib/mongoid/persistable/deletable.rb +5 -3
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +7 -14
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistable.rb +4 -6
- data/lib/mongoid/persistence_context.rb +220 -0
- data/lib/mongoid/query_cache.rb +67 -23
- data/lib/mongoid/railtie.rb +17 -1
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/accessors.rb +3 -0
- data/lib/mongoid/relations/auto_save.rb +12 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/counter_cache.rb +15 -5
- data/lib/mongoid/relations/eager/base.rb +3 -3
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
- data/lib/mongoid/relations/eager/has_many.rb +1 -1
- data/lib/mongoid/relations/eager.rb +6 -11
- data/lib/mongoid/relations/embedded/batchable.rb +20 -18
- data/lib/mongoid/relations/embedded/in.rb +13 -1
- data/lib/mongoid/relations/embedded/many.rb +51 -10
- data/lib/mongoid/relations/embedded/one.rb +14 -1
- data/lib/mongoid/relations/macros.rb +9 -1
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +1 -31
- data/lib/mongoid/relations/referenced/in.rb +19 -10
- data/lib/mongoid/relations/referenced/many.rb +30 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
- data/lib/mongoid/relations/referenced/one.rb +15 -1
- data/lib/mongoid/relations/synchronization.rb +12 -12
- data/lib/mongoid/relations/targets/enumerable.rb +24 -4
- data/lib/mongoid/relations/touchable.rb +7 -4
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/stateful.rb +1 -0
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +6 -6
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
- data/spec/app/models/agent.rb +2 -0
- data/spec/app/models/album.rb +5 -1
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/artist.rb +21 -0
- data/spec/app/models/band.rb +3 -0
- data/spec/app/models/book.rb +2 -1
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/dokument.rb +1 -0
- data/spec/app/models/ordered_post.rb +5 -0
- data/spec/app/models/oscar.rb +1 -2
- data/spec/app/models/page.rb +1 -1
- data/spec/app/models/person.rb +3 -3
- data/spec/app/models/princess.rb +2 -0
- data/spec/app/models/record.rb +1 -0
- data/spec/app/models/subscription.rb +1 -0
- data/spec/app/models/thing.rb +1 -1
- data/spec/config/mongoid.yml +15 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
- data/spec/mongoid/atomic_spec.rb +5 -5
- data/spec/mongoid/attributes/nested_spec.rb +18 -14
- data/spec/mongoid/attributes/readonly_spec.rb +87 -44
- data/spec/mongoid/attributes_spec.rb +90 -5
- data/spec/mongoid/cacheable_spec.rb +112 -0
- data/spec/mongoid/changeable_spec.rb +58 -0
- data/spec/mongoid/clients/factory_spec.rb +80 -28
- data/spec/mongoid/clients/options_spec.rb +396 -95
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/clients_spec.rb +243 -101
- data/spec/mongoid/composable_spec.rb +7 -0
- data/spec/mongoid/config_spec.rb +67 -11
- data/spec/mongoid/contextual/atomic_spec.rb +3 -3
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +275 -22
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +13 -4
- data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
- data/spec/mongoid/criteria/options_spec.rb +29 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
- data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +156 -22
- data/spec/mongoid/document_spec.rb +100 -90
- data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
- data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
- data/spec/mongoid/extensions/boolean_spec.rb +14 -0
- data/spec/mongoid/extensions/date_spec.rb +2 -6
- data/spec/mongoid/extensions/date_time_spec.rb +2 -6
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
- data/spec/mongoid/extensions/float_spec.rb +8 -1
- data/spec/mongoid/extensions/hash_spec.rb +15 -0
- data/spec/mongoid/extensions/integer_spec.rb +8 -1
- data/spec/mongoid/extensions/object_spec.rb +11 -0
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -4
- data/spec/mongoid/extensions/time_spec.rb +2 -6
- data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
- data/spec/mongoid/factory_spec.rb +11 -0
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +47 -2
- data/spec/mongoid/indexable_spec.rb +15 -3
- data/spec/mongoid/interceptable_spec.rb +85 -19
- data/spec/mongoid/matchable/all_spec.rb +4 -4
- data/spec/mongoid/matchable/and_spec.rb +10 -10
- data/spec/mongoid/matchable/default_spec.rb +12 -12
- data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
- data/spec/mongoid/matchable/exists_spec.rb +5 -5
- data/spec/mongoid/matchable/gt_spec.rb +18 -7
- data/spec/mongoid/matchable/gte_spec.rb +17 -7
- data/spec/mongoid/matchable/in_spec.rb +5 -5
- data/spec/mongoid/matchable/lt_spec.rb +18 -7
- data/spec/mongoid/matchable/lte_spec.rb +18 -7
- data/spec/mongoid/matchable/ne_spec.rb +5 -5
- data/spec/mongoid/matchable/nin_spec.rb +5 -5
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable/or_spec.rb +7 -7
- data/spec/mongoid/matchable/regexp_spec.rb +5 -5
- data/spec/mongoid/matchable/size_spec.rb +3 -3
- data/spec/mongoid/matchable_spec.rb +199 -54
- data/spec/mongoid/persistable/creatable_spec.rb +7 -2
- data/spec/mongoid/persistable/deletable_spec.rb +35 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/savable_spec.rb +34 -29
- data/spec/mongoid/persistable/settable_spec.rb +77 -27
- data/spec/mongoid/persistable/updatable_spec.rb +182 -3
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/persistence_context_spec.rb +694 -0
- data/spec/mongoid/positional_spec.rb +1 -1
- data/spec/mongoid/query_cache_spec.rb +170 -12
- data/spec/mongoid/relations/accessors_spec.rb +1 -1
- data/spec/mongoid/relations/auto_save_spec.rb +39 -6
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
- data/spec/mongoid/relations/builders_spec.rb +37 -10
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
- data/spec/mongoid/relations/eager_spec.rb +40 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
- data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
- data/spec/mongoid/relations/macros_spec.rb +415 -7
- data/spec/mongoid/relations/metadata_spec.rb +15 -1
- data/spec/mongoid/relations/proxy_spec.rb +27 -1
- data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
- data/spec/mongoid/relations/synchronization_spec.rb +48 -2
- data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
- data/spec/mongoid/relations/touchable_spec.rb +40 -0
- data/spec/mongoid/reloadable_spec.rb +51 -0
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/serializable_spec.rb +0 -50
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
- data/spec/mongoid/validatable_spec.rb +16 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +101 -8
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +42 -0
- data.tar.gz.sig +0 -0
- metadata +163 -61
- metadata.gz.sig +0 -0
- data/lib/mongoid/clients/thread_options.rb +0 -19
- data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
- data/lib/mongoid/railties/document.rb +0 -12
- data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -30,7 +30,7 @@ describe Mongoid::Persistable::Destroyable do
|
|
30
30
|
it "destroys the document from the collection" do
|
31
31
|
expect {
|
32
32
|
Person.find(person.id)
|
33
|
-
}.to raise_error
|
33
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
34
34
|
end
|
35
35
|
|
36
36
|
it "returns true" do
|
@@ -164,7 +164,11 @@ describe Mongoid::Persistable::Destroyable do
|
|
164
164
|
end
|
165
165
|
|
166
166
|
before do
|
167
|
-
|
167
|
+
Album.before_destroy(:set_parent_name_fail)
|
168
|
+
end
|
169
|
+
|
170
|
+
after do
|
171
|
+
Album.reset_callbacks(:destroy)
|
168
172
|
end
|
169
173
|
|
170
174
|
it "raises an exception" do
|
@@ -218,6 +222,25 @@ describe Mongoid::Persistable::Destroyable do
|
|
218
222
|
end
|
219
223
|
end
|
220
224
|
|
225
|
+
context 'when the write concern is unacknowledged' do
|
226
|
+
|
227
|
+
before do
|
228
|
+
Person.create(title: 'miss')
|
229
|
+
end
|
230
|
+
|
231
|
+
let!(:removed) do
|
232
|
+
Person.with(write: { w: 0 }) { |klass| klass.destroy_all(title: "sir") }
|
233
|
+
end
|
234
|
+
|
235
|
+
it "removes the matching documents" do
|
236
|
+
expect(Person.where(title: 'miss').count).to eq(1)
|
237
|
+
end
|
238
|
+
|
239
|
+
it "returns 0" do
|
240
|
+
expect(removed).to eq(0)
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
221
244
|
context 'when removing a list of embedded documents' do
|
222
245
|
|
223
246
|
context 'when the embedded documents list is reversed in memory' do
|
@@ -66,15 +66,15 @@ describe Mongoid::Persistable::Incrementable do
|
|
66
66
|
context "when providing big decimal values" do
|
67
67
|
|
68
68
|
let(:five) do
|
69
|
-
BigDecimal
|
69
|
+
BigDecimal("5.0")
|
70
70
|
end
|
71
71
|
|
72
72
|
let(:neg_ten) do
|
73
|
-
BigDecimal
|
73
|
+
BigDecimal("-10.0")
|
74
74
|
end
|
75
75
|
|
76
76
|
let(:thirty) do
|
77
|
-
BigDecimal
|
77
|
+
BigDecimal("30.0")
|
78
78
|
end
|
79
79
|
|
80
80
|
let!(:inc) do
|
@@ -151,15 +151,15 @@ describe Mongoid::Persistable::Incrementable do
|
|
151
151
|
context "when providing big decimal values" do
|
152
152
|
|
153
153
|
let(:five) do
|
154
|
-
BigDecimal
|
154
|
+
BigDecimal("5.0")
|
155
155
|
end
|
156
156
|
|
157
157
|
let(:neg_ten) do
|
158
|
-
BigDecimal
|
158
|
+
BigDecimal("-10.0")
|
159
159
|
end
|
160
160
|
|
161
161
|
let(:thirty) do
|
162
|
-
BigDecimal
|
162
|
+
BigDecimal("30.0")
|
163
163
|
end
|
164
164
|
|
165
165
|
let!(:inc) do
|
@@ -190,7 +190,7 @@ describe Mongoid::Persistable::Savable do
|
|
190
190
|
"name.first_name" => "Ryan"
|
191
191
|
},
|
192
192
|
"$push"=> {
|
193
|
-
"addresses" =>
|
193
|
+
"addresses" => { '$each' => [ { "_id" => address.id, "street" => "Bond St" } ] }
|
194
194
|
}
|
195
195
|
})
|
196
196
|
end
|
@@ -295,20 +295,37 @@ describe Mongoid::Persistable::Savable do
|
|
295
295
|
end
|
296
296
|
end
|
297
297
|
|
298
|
-
context "when the
|
299
|
-
|
300
|
-
let(:person) do
|
301
|
-
Person.only(:title).first
|
302
|
-
end
|
298
|
+
context "when the changed attribute is not writable" do
|
303
299
|
|
304
300
|
before do
|
305
301
|
Person.create(title: "sir")
|
306
302
|
end
|
307
303
|
|
304
|
+
let(:person) do
|
305
|
+
Person.only(:title).first
|
306
|
+
end
|
307
|
+
|
308
308
|
it "raises an error" do
|
309
309
|
expect {
|
310
|
+
person.username = 'unloaded-attribute'
|
310
311
|
person.save
|
311
|
-
}.to raise_error(Mongoid::Errors::
|
312
|
+
}.to raise_error(Mongoid::Errors::ReadonlyAttribute)
|
313
|
+
end
|
314
|
+
|
315
|
+
context 'when the changed attribute is aliased' do
|
316
|
+
|
317
|
+
before do
|
318
|
+
Person.create(at: Time.now)
|
319
|
+
end
|
320
|
+
|
321
|
+
let(:person) do
|
322
|
+
Person.only(:at).first
|
323
|
+
end
|
324
|
+
|
325
|
+
it "saves the document" do
|
326
|
+
person.aliased_timestamp = Time.now
|
327
|
+
expect(person.save(validate: false)).to be true
|
328
|
+
end
|
312
329
|
end
|
313
330
|
end
|
314
331
|
|
@@ -353,12 +370,17 @@ describe Mongoid::Persistable::Savable do
|
|
353
370
|
end
|
354
371
|
|
355
372
|
before do
|
373
|
+
Person.index({ ssn: 1 }, { unique: true })
|
356
374
|
Person.create_indexes
|
357
375
|
Person.create!(ssn: "555-55-9999")
|
358
376
|
end
|
359
377
|
|
360
|
-
|
361
|
-
|
378
|
+
after do
|
379
|
+
Person.collection.drop
|
380
|
+
end
|
381
|
+
|
382
|
+
it "raises an OperationFailure" do
|
383
|
+
expect { person.save! }.to raise_error(Mongo::Error::OperationFailure)
|
362
384
|
end
|
363
385
|
end
|
364
386
|
end
|
@@ -374,12 +396,12 @@ describe Mongoid::Persistable::Savable do
|
|
374
396
|
end
|
375
397
|
|
376
398
|
it "raises an error with multiple save attempts" do
|
377
|
-
expect {
|
378
|
-
expect {
|
399
|
+
expect { service.save! }.to raise_error(Mongoid::Errors::Validations)
|
400
|
+
expect { service.save! }.to raise_error(Mongoid::Errors::Validations)
|
379
401
|
end
|
380
402
|
end
|
381
403
|
|
382
|
-
context "when a callback
|
404
|
+
context "when a callback aborts the callback chain" do
|
383
405
|
|
384
406
|
let(:oscar) do
|
385
407
|
Oscar.new
|
@@ -495,22 +517,5 @@ describe Mongoid::Persistable::Savable do
|
|
495
517
|
expect(from_db.shapes.first.canvas).to eq(firefox)
|
496
518
|
end
|
497
519
|
end
|
498
|
-
|
499
|
-
context "when the document is readonly" do
|
500
|
-
|
501
|
-
let(:person) do
|
502
|
-
Person.only(:title).first
|
503
|
-
end
|
504
|
-
|
505
|
-
before do
|
506
|
-
Person.create(title: "sir")
|
507
|
-
end
|
508
|
-
|
509
|
-
it "raises an error" do
|
510
|
-
expect {
|
511
|
-
person.save!
|
512
|
-
}.to raise_error(Mongoid::Errors::ReadonlyDocument)
|
513
|
-
end
|
514
|
-
end
|
515
520
|
end
|
516
521
|
end
|
@@ -230,6 +230,22 @@ describe Mongoid::Persistable::Settable do
|
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
233
|
+
context 'when the field is assigned with nil' do
|
234
|
+
|
235
|
+
before do
|
236
|
+
church.location = nil
|
237
|
+
church.set('location.neighborhood' => 'Kreuzberg')
|
238
|
+
end
|
239
|
+
|
240
|
+
it 'updates the hash while keeping existing key and values locally' do
|
241
|
+
expect(church.location).to eq({'neighborhood' => 'Kreuzberg'})
|
242
|
+
end
|
243
|
+
|
244
|
+
it 'updates the hash in the database' do
|
245
|
+
expect(church.reload.location).to eq({'neighborhood' => 'Kreuzberg'})
|
246
|
+
end
|
247
|
+
end
|
248
|
+
|
233
249
|
context 'when the field type is String' do
|
234
250
|
|
235
251
|
before do
|
@@ -261,48 +277,82 @@ describe Mongoid::Persistable::Settable do
|
|
261
277
|
expect(church.reload.location).to eq({ 'city' => 'Berlin', 'street' => 'Yorckstr.'})
|
262
278
|
end
|
263
279
|
end
|
264
|
-
end
|
265
280
|
|
266
|
-
|
281
|
+
context 'when the field is a nested hash' do
|
267
282
|
|
268
|
-
|
283
|
+
context 'when the field is reset to an empty hash' do
|
269
284
|
|
270
|
-
|
271
|
-
|
272
|
-
a.location = {'address' => {'city' => 'Berlin', 'street' => 'Yorckstr'}}
|
273
|
-
a.name = 'Church1'
|
274
|
-
a.save
|
285
|
+
before do
|
286
|
+
church.set('location' => {})
|
275
287
|
end
|
276
|
-
end
|
277
288
|
|
278
|
-
|
279
|
-
|
280
|
-
|
289
|
+
it 'updates the field locally' do
|
290
|
+
expect(church.location).to eq({})
|
291
|
+
end
|
281
292
|
|
282
|
-
|
283
|
-
|
284
|
-
|
293
|
+
it 'updates the field in the database' do
|
294
|
+
expect(church.reload.location).to eq({})
|
295
|
+
end
|
285
296
|
end
|
286
|
-
end
|
287
297
|
|
298
|
+
context 'when a leaf value in the nested hash is updated' do
|
288
299
|
|
289
|
-
|
300
|
+
let(:church) do
|
301
|
+
Church.new.tap do |a|
|
302
|
+
a.location = {'address' => {'city' => 'Berlin', 'street' => 'Yorckstr'}}
|
303
|
+
a.name = 'Church1'
|
304
|
+
a.save
|
305
|
+
end
|
306
|
+
end
|
290
307
|
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
308
|
+
before do
|
309
|
+
church.set('location.address.city' => 'Munich')
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'does not reset the nested hash' do
|
313
|
+
expect(church.name).to eq('Church1')
|
314
|
+
expect(church.location).to eql({'address' => {'city' => 'Munich', 'street' => 'Yorckstr'}})
|
296
315
|
end
|
297
316
|
end
|
298
317
|
|
299
|
-
|
300
|
-
|
318
|
+
context 'when a leaf value in the nested hash is updated to a number' do
|
319
|
+
|
320
|
+
let(:church) do
|
321
|
+
Church.new.tap do |a|
|
322
|
+
a.location = {'address' => {'city' => 'Berlin', 'street' => 'Yorckstr'}}
|
323
|
+
a.name = 'Church1'
|
324
|
+
a.save
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
before do
|
329
|
+
church.set('location.address.city' => 12345)
|
330
|
+
end
|
331
|
+
|
332
|
+
it 'updates the nested value to the correct value' do
|
333
|
+
expect(church.name).to eq('Church1')
|
334
|
+
expect(church.location).to eql({'address' => {'city' => 12345, 'street' => 'Yorckstr'}})
|
335
|
+
end
|
301
336
|
end
|
302
337
|
|
303
|
-
|
304
|
-
|
305
|
-
|
338
|
+
context 'when the nested hash is many levels deep' do
|
339
|
+
|
340
|
+
let(:church) do
|
341
|
+
Church.new.tap do |a|
|
342
|
+
a.location = {'address' => {'state' => {'address' => {'city' => 'Berlin', 'street' => 'Yorckstr'}}}}
|
343
|
+
a.name = 'Church1'
|
344
|
+
a.save
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
before do
|
349
|
+
church.set('location.address.state.address.city' => 'Munich')
|
350
|
+
end
|
351
|
+
|
352
|
+
it 'does not reset the nested hash' do
|
353
|
+
expect(church.name).to eq('Church1')
|
354
|
+
expect(church.location).to eql({'address' => {'state' => {'address' => {'city' => 'Munich', 'street' => 'Yorckstr'}}}})
|
355
|
+
end
|
306
356
|
end
|
307
357
|
end
|
308
358
|
end
|
@@ -112,6 +112,24 @@ describe Mongoid::Persistable::Updatable do
|
|
112
112
|
end
|
113
113
|
end
|
114
114
|
|
115
|
+
context "when dynamic attributes are not enabled" do
|
116
|
+
|
117
|
+
it "raises exception for an unknown attribute " do
|
118
|
+
account = Account.create
|
119
|
+
|
120
|
+
expect {
|
121
|
+
account.update_attribute(:somethingnew, "somethingnew")
|
122
|
+
}.to raise_error(Mongoid::Errors::UnknownAttribute)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "will update value of aliased field" do
|
126
|
+
person = Person.create
|
127
|
+
person.update_attribute(:t, "test_value")
|
128
|
+
expect(person.reload.t).to eq "test_value"
|
129
|
+
expect(person.test).to eq "test_value"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
115
133
|
context "when provided a symbol attribute name" do
|
116
134
|
|
117
135
|
let(:post) do
|
@@ -168,7 +186,7 @@ describe Mongoid::Persistable::Updatable do
|
|
168
186
|
it "raises an error" do
|
169
187
|
expect {
|
170
188
|
post.update_attribute(:title, "something")
|
171
|
-
}.to raise_error
|
189
|
+
}.to raise_error(RuntimeError)
|
172
190
|
end
|
173
191
|
end
|
174
192
|
end
|
@@ -269,6 +287,167 @@ describe Mongoid::Persistable::Updatable do
|
|
269
287
|
expect(from_db.reload.name).to eq("home")
|
270
288
|
end
|
271
289
|
end
|
290
|
+
|
291
|
+
context 'when the field is read-only' do
|
292
|
+
|
293
|
+
before do
|
294
|
+
Person.attr_readonly :species
|
295
|
+
end
|
296
|
+
|
297
|
+
after do
|
298
|
+
Person.readonly_attributes.reject! { |a| a.to_s == 'species' }
|
299
|
+
end
|
300
|
+
|
301
|
+
let(:person) do
|
302
|
+
Person.create(species: :human)
|
303
|
+
end
|
304
|
+
|
305
|
+
it 'raises an error when trying to set the attribute' do
|
306
|
+
expect {
|
307
|
+
person.update_attribute(:species, :reptile)
|
308
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
309
|
+
end
|
310
|
+
|
311
|
+
context 'when referring to the attribute with a string' do
|
312
|
+
|
313
|
+
it 'raises an error when trying to set the attribute' do
|
314
|
+
expect {
|
315
|
+
person.update_attribute('species', :reptile)
|
316
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
|
320
|
+
context 'when the field is aliased' do
|
321
|
+
|
322
|
+
before do
|
323
|
+
Person.attr_readonly :at
|
324
|
+
end
|
325
|
+
|
326
|
+
after do
|
327
|
+
Person.readonly_attributes.reject! { |a| a.to_s == 'at' }
|
328
|
+
end
|
329
|
+
|
330
|
+
it 'raises an error when trying to set the attribute using the db name' do
|
331
|
+
expect {
|
332
|
+
person.update_attribute(:at, Time.now)
|
333
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'raises an error when trying to set the attribute using the aliased name' do
|
337
|
+
expect {
|
338
|
+
person.update_attribute(:aliased_timestamp, Time.now)
|
339
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
343
|
+
|
344
|
+
context 'when the field is loaded explicitly' do
|
345
|
+
|
346
|
+
before do
|
347
|
+
Person.create(title: 'Captain')
|
348
|
+
end
|
349
|
+
|
350
|
+
context 'when the loaded attribute is updated' do
|
351
|
+
|
352
|
+
let(:person) do
|
353
|
+
Person.only(:title).first.tap do |_person|
|
354
|
+
_person.update_attribute(:title, 'Esteemed')
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
it 'allows the field to be updated' do
|
359
|
+
expect(person.title).to eq('Esteemed')
|
360
|
+
end
|
361
|
+
|
362
|
+
it 'persists the updated field' do
|
363
|
+
expect(person.reload.title).to eq('Esteemed')
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
context 'when the an attribute other than the loaded one is updated' do
|
368
|
+
|
369
|
+
let(:person) do
|
370
|
+
Person.only(:title).first
|
371
|
+
end
|
372
|
+
|
373
|
+
it 'does not allow the field to be updated' do
|
374
|
+
expect {
|
375
|
+
person.update_attribute(:age, 20)
|
376
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
377
|
+
end
|
378
|
+
|
379
|
+
it 'does not persist the change' do
|
380
|
+
expect(person.reload.age).to eq(100)
|
381
|
+
end
|
382
|
+
|
383
|
+
context 'when referring to the attribute with a string' do
|
384
|
+
|
385
|
+
it 'does not allow the field to be updated' do
|
386
|
+
expect {
|
387
|
+
person.update_attribute('age', 20)
|
388
|
+
}.to raise_exception(Mongoid::Errors::ReadonlyAttribute)
|
389
|
+
end
|
390
|
+
|
391
|
+
it 'does not persist the change' do
|
392
|
+
expect(person.reload.age).to eq(100)
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
context 'when fields are explicitly not loaded' do
|
399
|
+
|
400
|
+
before do
|
401
|
+
Person.create(title: 'Captain')
|
402
|
+
end
|
403
|
+
|
404
|
+
context 'when the loaded attribute is updated' do
|
405
|
+
|
406
|
+
let(:person) do
|
407
|
+
Person.without(:age).first.tap do |_person|
|
408
|
+
_person.update_attribute(:title, 'Esteemed')
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'allows the field to be updated' do
|
413
|
+
expect(person.title).to eq('Esteemed')
|
414
|
+
end
|
415
|
+
|
416
|
+
it 'persists the updated field' do
|
417
|
+
expect(person.reload.title).to eq('Esteemed')
|
418
|
+
end
|
419
|
+
end
|
420
|
+
|
421
|
+
context 'when the non-loaded attribute is updated' do
|
422
|
+
|
423
|
+
let(:person) do
|
424
|
+
Person.without(:title).first
|
425
|
+
end
|
426
|
+
|
427
|
+
it 'does not allow the field to be updated' do
|
428
|
+
expect {
|
429
|
+
person.update_attribute(:title, 'Esteemed')
|
430
|
+
}.to raise_exception(ActiveModel::MissingAttributeError)
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'does not persist the change' do
|
434
|
+
expect(person.reload.title).to eq('Captain')
|
435
|
+
end
|
436
|
+
|
437
|
+
context 'when referring to the attribute with a string' do
|
438
|
+
|
439
|
+
it 'does not allow the field to be updated' do
|
440
|
+
expect {
|
441
|
+
person.update_attribute('title', 'Esteemed')
|
442
|
+
}.to raise_exception(ActiveModel::MissingAttributeError)
|
443
|
+
end
|
444
|
+
|
445
|
+
it 'does not persist the change' do
|
446
|
+
expect(person.reload.title).to eq('Captain')
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
272
451
|
end
|
273
452
|
|
274
453
|
[:update_attributes, :update].each do |method|
|
@@ -360,7 +539,7 @@ describe Mongoid::Persistable::Updatable do
|
|
360
539
|
it "raises an error" do
|
361
540
|
expect {
|
362
541
|
person.send(method, title: "something")
|
363
|
-
}.to raise_error
|
542
|
+
}.to raise_error(RuntimeError)
|
364
543
|
end
|
365
544
|
end
|
366
545
|
|
@@ -543,7 +722,7 @@ describe Mongoid::Persistable::Updatable do
|
|
543
722
|
|
544
723
|
describe "#update!" do
|
545
724
|
|
546
|
-
context "when a callback
|
725
|
+
context "when a callback aborts the callback chain" do
|
547
726
|
|
548
727
|
let(:oscar) do
|
549
728
|
Oscar.new
|
@@ -52,16 +52,16 @@ describe Mongoid::Persistable do
|
|
52
52
|
context "when not chaining the operations" do
|
53
53
|
|
54
54
|
let(:operations) do
|
55
|
-
{
|
55
|
+
[{
|
56
56
|
"$inc" => { "member_count" => 10 },
|
57
57
|
"$bit" => { "likes" => { :and => 13 }},
|
58
58
|
"$set" => { "name" => "Placebo" },
|
59
|
-
"$unset" => { "origin" => true }
|
60
|
-
|
59
|
+
"$unset" => { "origin" => true }},
|
60
|
+
{ session: nil }]
|
61
61
|
end
|
62
62
|
|
63
63
|
before do
|
64
|
-
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(operations).and_call_original
|
64
|
+
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(*operations).and_call_original
|
65
65
|
end
|
66
66
|
|
67
67
|
let!(:update) do
|
@@ -79,16 +79,16 @@ describe Mongoid::Persistable do
|
|
79
79
|
context "when chaining the operations" do
|
80
80
|
|
81
81
|
let(:operations) do
|
82
|
-
{
|
82
|
+
[{
|
83
83
|
"$inc" => { "member_count" => 10 },
|
84
84
|
"$bit" => { "likes" => { :and => 13 }},
|
85
85
|
"$set" => { "name" => "Placebo" },
|
86
|
-
"$unset" => { "origin" => true }
|
87
|
-
|
86
|
+
"$unset" => { "origin" => true }},
|
87
|
+
{ :session => nil } ]
|
88
88
|
end
|
89
89
|
|
90
90
|
before do
|
91
|
-
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(operations).and_call_original
|
91
|
+
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(*operations).and_call_original
|
92
92
|
end
|
93
93
|
|
94
94
|
let!(:update) do
|
@@ -107,16 +107,16 @@ describe Mongoid::Persistable do
|
|
107
107
|
context "when given multiple operations of the same type" do
|
108
108
|
|
109
109
|
let(:operations) do
|
110
|
-
{
|
110
|
+
[{
|
111
111
|
"$inc" => { "member_count" => 10, "other_count" => 10 },
|
112
112
|
"$bit" => { "likes" => { :and => 13 }},
|
113
113
|
"$set" => { "name" => "Placebo" },
|
114
|
-
"$unset" => { "origin" => true }
|
115
|
-
|
114
|
+
"$unset" => { "origin" => true }},
|
115
|
+
{ session: nil }]
|
116
116
|
end
|
117
117
|
|
118
118
|
before do
|
119
|
-
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(operations).and_call_original
|
119
|
+
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(*operations).and_call_original
|
120
120
|
end
|
121
121
|
|
122
122
|
let!(:update) do
|
@@ -144,16 +144,16 @@ describe Mongoid::Persistable do
|
|
144
144
|
context "when expecting the document to be yielded" do
|
145
145
|
|
146
146
|
let(:operations) do
|
147
|
-
{
|
147
|
+
[{
|
148
148
|
"$inc" => { "member_count" => 10 },
|
149
149
|
"$bit" => { "likes" => { :and => 13 }},
|
150
150
|
"$set" => { "name" => "Placebo" },
|
151
|
-
"$unset" => { "origin" => true }
|
152
|
-
|
151
|
+
"$unset" => { "origin" => true }},
|
152
|
+
{ session: nil }]
|
153
153
|
end
|
154
154
|
|
155
155
|
before do
|
156
|
-
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(operations).and_call_original
|
156
|
+
expect_any_instance_of(Mongo::Collection::View).to receive(:update_one).with(*operations).and_call_original
|
157
157
|
end
|
158
158
|
|
159
159
|
let!(:update) do
|