mongoid 6.2.1 → 6.3.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.
@@ -76,13 +76,13 @@ describe Mongoid::Atomic do
76
76
  person.addresses.build(street: "Oxford St")
77
77
  end
78
78
 
79
- it "returns a $set and $pushAll for modifications" do
79
+ it "returns a $set and $push for modifications" do
80
80
  expect(person.atomic_updates).to eq(
81
81
  {
82
82
  "$set" => { "title" => "Sir" },
83
- "$pushAll" => { "addresses" => [
83
+ "$push" => { "addresses" => { '$each' => [
84
84
  { "_id" => "oxford-st", "street" => "Oxford St" }
85
- ]}
85
+ ]} }
86
86
  }
87
87
  )
88
88
  end
@@ -197,8 +197,8 @@ describe Mongoid::Atomic do
197
197
  "addresses.0.street" => "Bond St"
198
198
  },
199
199
  conflicts: {
200
- "$pushAll" => {
201
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
200
+ "$push" => {
201
+ "addresses.0.locations" => { '$each' => [{ "_id" => location.id, "name" => "Home" }] }
202
202
  }
203
203
  }
204
204
  }
@@ -215,8 +215,8 @@ describe Mongoid::Atomic do
215
215
  "addresses.0.street" => "Bond St"
216
216
  },
217
217
  conflicts: {
218
- "$pushAll" => {
219
- "addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
218
+ "$push" => {
219
+ "addresses.0.locations" => { '$each' => [{ "_id" => location.id, "name" => "Home" }] }
220
220
  }
221
221
  }
222
222
  }
@@ -263,15 +263,15 @@ describe Mongoid::Atomic do
263
263
  "addresses.0.street" => "Bond St"
264
264
  },
265
265
  conflicts: {
266
- "$pushAll" => {
267
- "addresses" => [{
266
+ "$push" => {
267
+ "addresses" => { '$each' => [{
268
268
  "_id" => new_address.id,
269
269
  "street" => "Another",
270
270
  "locations" => [
271
271
  "_id" => location.id,
272
272
  "name" => "Home"
273
273
  ]
274
- }]
274
+ }] }
275
275
  }
276
276
  }
277
277
  }
@@ -310,15 +310,15 @@ describe Mongoid::Atomic do
310
310
  "$set" => {
311
311
  "title" => "Sir"
312
312
  },
313
- "$pushAll" => {
314
- "addresses" => [{
313
+ "$push" => {
314
+ "addresses" => { '$each' => [{
315
315
  "_id" => new_address.id,
316
316
  "street" => "Ipanema",
317
317
  "locations" => [
318
318
  "_id" => location.id,
319
319
  "name" => "Home"
320
320
  ]
321
- }]
321
+ }] }
322
322
  },
323
323
  conflicts: {
324
324
  "$set" => { "addresses.0.street"=>"Bond St" }
@@ -339,21 +339,21 @@ describe Mongoid::Atomic do
339
339
  address.locations.build(name: "Home")
340
340
  end
341
341
 
342
- it "returns the proper $sets and $pushAlls for all levels" do
342
+ it "returns the proper $sets and $pushes for all levels" do
343
343
  expect(person.atomic_updates).to eq(
344
344
  {
345
345
  "$set" => {
346
346
  "title" => "Sir",
347
347
  },
348
- "$pushAll" => {
349
- "addresses" => [{
348
+ "$push" => {
349
+ "addresses" => { '$each' => [{
350
350
  "_id" => address.id,
351
351
  "street" => "Another",
352
352
  "locations" => [
353
353
  "_id" => location.id,
354
354
  "name" => "Home"
355
355
  ]
356
- }]
356
+ }] }
357
357
  }
358
358
  }
359
359
  )
@@ -2094,6 +2094,41 @@ describe Mongoid::Contextual::Mongo do
2094
2094
  expect(context.update).to be false
2095
2095
  end
2096
2096
  end
2097
+
2098
+ context 'when provided array filters', if: array_filters_supported? do
2099
+
2100
+ before do
2101
+ Band.delete_all
2102
+ b = Band.new(name: 'Depeche Mode')
2103
+ b.labels << Label.new(name: 'Warner')
2104
+ b.labels << Label.new(name: 'Sony')
2105
+ b.labels << Label.new(name: 'Cbs')
2106
+ b.save
2107
+
2108
+ b = Band.new(name: 'FKA Twigs')
2109
+ b.labels << Label.new(name: 'Warner')
2110
+ b.labels << Label.new(name: 'Cbs')
2111
+ b.save
2112
+ end
2113
+
2114
+
2115
+ let(:criteria) do
2116
+ Band.where(name: 'Depeche Mode')
2117
+ end
2118
+
2119
+ let!(:update) do
2120
+ context.update({ '$set' => { 'labels.$[i].name' => 'Sony' } },
2121
+ array_filters: [{ 'i.name' => 'Cbs' }])
2122
+ end
2123
+
2124
+ it 'applies the array filters' do
2125
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
2126
+ end
2127
+
2128
+ it 'does not affect other documents' do
2129
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Cbs'])
2130
+ end
2131
+ end
2097
2132
  end
2098
2133
 
2099
2134
  describe "#update_all" do
@@ -2231,6 +2266,41 @@ describe Mongoid::Contextual::Mongo do
2231
2266
  expect(context.update_all).to be false
2232
2267
  end
2233
2268
  end
2269
+
2270
+ context 'when provided array filters', if: array_filters_supported? do
2271
+
2272
+ before do
2273
+ Band.delete_all
2274
+ b = Band.new(name: 'Depeche Mode')
2275
+ b.labels << Label.new(name: 'Warner')
2276
+ b.labels << Label.new(name: 'Sony')
2277
+ b.labels << Label.new(name: 'Cbs')
2278
+ b.save
2279
+
2280
+ b = Band.new(name: 'FKA Twigs')
2281
+ b.labels << Label.new(name: 'Warner')
2282
+ b.labels << Label.new(name: 'Cbs')
2283
+ b.save
2284
+ end
2285
+
2286
+
2287
+ let(:criteria) do
2288
+ Band.all
2289
+ end
2290
+
2291
+ let!(:update) do
2292
+ context.update_all({ '$set' => { 'labels.$[i].name' => 'Sony' } },
2293
+ array_filters: [{ 'i.name' => 'Cbs' }])
2294
+ end
2295
+
2296
+ it 'applies the array filters' do
2297
+ expect(Band.where(name: 'Depeche Mode').first.labels.collect(&:name)).to match_array(['Warner', 'Sony', 'Sony'])
2298
+ end
2299
+
2300
+ it 'updates all documents' do
2301
+ expect(Band.where(name: 'FKA Twigs').first.labels.collect(&:name)).to match_array(['Warner', 'Sony'])
2302
+ end
2303
+ end
2234
2304
  end
2235
2305
 
2236
2306
  describe '#pipeline' do
@@ -88,6 +88,17 @@ describe Mongoid::Factory do
88
88
  expect(person.title).to eq("Sir")
89
89
  end
90
90
  end
91
+
92
+ context "when the type is a symbol" do
93
+
94
+ let(:person) do
95
+ described_class.build(Person, {:_type => "Doctor"})
96
+ end
97
+
98
+ it "instantiates the subclass" do
99
+ expect(person.class).to eq(Doctor)
100
+ end
101
+ end
91
102
  end
92
103
 
93
104
  describe ".from_db" do
@@ -189,8 +189,8 @@ describe Mongoid::Persistable::Savable do
189
189
  "title" => "King",
190
190
  "name.first_name" => "Ryan"
191
191
  },
192
- "$pushAll"=> {
193
- "addresses" => [ { "_id" => address.id, "street" => "Bond St" } ]
192
+ "$push"=> {
193
+ "addresses" => { '$each' => [ { "_id" => address.id, "street" => "Bond St" } ] }
194
194
  }
195
195
  })
196
196
  end
@@ -462,7 +462,7 @@ describe Mongoid::Persistable::Updatable do
462
462
 
463
463
  it "raises an error" do
464
464
  expect {
465
- person.update_attributes(map: { "bad.key" => "value" })
465
+ person.update_attributes(map: { "$bad.key" => "value" })
466
466
  }.to raise_error(Mongo::Error::OperationFailure)
467
467
  end
468
468
  end
@@ -498,7 +498,7 @@ describe Mongoid::Persistable::Updatable do
498
498
 
499
499
  it "raises an error" do
500
500
  expect {
501
- person.send(method, map: { "bad.key" => "value" })
501
+ person.send(method, map: { "$bad.key" => "value" })
502
502
  }.to raise_error(Mongo::Error::OperationFailure)
503
503
  end
504
504
  end
@@ -70,6 +70,20 @@ describe Mongoid::PersistenceContext do
70
70
  { collection: :other }
71
71
  end
72
72
 
73
+ context 'when the method throws an error' do
74
+
75
+ let!(:persistence_context) do
76
+ described_class.set(object, options).tap do |cxt|
77
+ allow(cxt).to receive(:client).and_raise(Mongoid::Errors::NoClientConfig.new('default'))
78
+ end
79
+ end
80
+
81
+ it 'clears the context anyway' do
82
+ begin; described_class.clear(object); rescue; end
83
+ expect(described_class.get(object)).to be(nil)
84
+ end
85
+ end
86
+
73
87
  context 'when there has been a persistence context set on the current thread' do
74
88
 
75
89
  let!(:persistence_context) do
@@ -17,8 +17,8 @@ describe Mongoid::Positional do
17
17
  "children.0.field" => "value",
18
18
  "children.0.children.1.children.3.field" => "value"
19
19
  },
20
- "$pushAll" => {
21
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
20
+ "$push" => {
21
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
22
22
  }
23
23
  }
24
24
  end
@@ -113,8 +113,8 @@ describe Mongoid::Positional do
113
113
  "children.$.field" => "value",
114
114
  "children.0.children.1.children.3.field" => "value"
115
115
  },
116
- "$pushAll" => {
117
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
116
+ "$push" => {
117
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
118
118
  }
119
119
  }
120
120
  end
@@ -141,8 +141,8 @@ describe Mongoid::Positional do
141
141
  "children.0.field" => "value",
142
142
  "children.0.children.1.children.3.field" => "value"
143
143
  },
144
- "$pushAll" => {
145
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
144
+ "$push" => {
145
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
146
146
  }
147
147
  }
148
148
  end
@@ -170,8 +170,8 @@ describe Mongoid::Positional do
170
170
  "children.$.field" => "value",
171
171
  "children.0.children.1.children.3.field" => "value"
172
172
  },
173
- "$pushAll" => {
174
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
173
+ "$push" => {
174
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
175
175
  }
176
176
  }
177
177
  end
@@ -203,8 +203,8 @@ describe Mongoid::Positional do
203
203
  "children.$.field" => "value",
204
204
  "children.0.children.1.children.3.field" => "value"
205
205
  },
206
- "$pushAll" => {
207
- "children.0.children.1.children.3.fields" => [ "value", "value" ]
206
+ "$push" => {
207
+ "children.0.children.1.children.3.fields" => { '$each' => [ "value", "value" ] }
208
208
  }
209
209
  }
210
210
  end
@@ -20,6 +20,26 @@ describe Mongoid::Relations::Macros do
20
20
  klass.validators.clear
21
21
  end
22
22
 
23
+ describe 'Model loading' do
24
+
25
+ let(:model_associations) do
26
+ class TestModel
27
+ include Mongoid::Document
28
+ field :associations
29
+ end
30
+ end
31
+
32
+ after do
33
+ Object.send(:remove_const, :TestModel)
34
+ end
35
+
36
+ it 'prohibits the use of :associations as an attribute' do
37
+ expect {
38
+ model_associations
39
+ }.to raise_exception(Mongoid::Errors::InvalidField)
40
+ end
41
+ end
42
+
23
43
  describe ".embedded_in" do
24
44
 
25
45
  it "defines the macro" do
@@ -928,6 +928,60 @@ describe Mongoid::Relations::Targets::Enumerable do
928
928
  end
929
929
  end
930
930
  end
931
+
932
+ context 'when the id_sort option is none' do
933
+
934
+ let(:person) do
935
+ Person.create
936
+ end
937
+
938
+ let(:criteria) do
939
+ Post.where(person_id: person.id)
940
+ end
941
+
942
+ let(:enumerable) do
943
+ described_class.new(criteria)
944
+ end
945
+
946
+ let!(:first_post) do
947
+ person.posts.create(title: "One")
948
+ end
949
+
950
+ let!(:second_post) do
951
+ person.posts.create(title: "Two")
952
+ end
953
+
954
+ it 'does not use the sort on id' do
955
+ expect(enumerable.first(id_sort: :none)).to eq(first_post)
956
+ end
957
+ end
958
+
959
+ context 'when the id_sort option is not provided' do
960
+
961
+ let(:person) do
962
+ Person.create
963
+ end
964
+
965
+ let(:criteria) do
966
+ Post.where(person_id: person.id)
967
+ end
968
+
969
+ let(:enumerable) do
970
+ described_class.new(criteria)
971
+ end
972
+
973
+ let!(:first_post) do
974
+ person.posts.create(title: "One")
975
+ end
976
+
977
+ let!(:second_post) do
978
+ person.posts.create(title: "Two")
979
+ end
980
+
981
+ it 'uses the sort on id' do
982
+ expect(enumerable.first).to eq(first_post)
983
+ end
984
+ end
931
985
  end
932
986
 
933
987
  describe "#include?" do
@@ -1344,6 +1398,60 @@ describe Mongoid::Relations::Targets::Enumerable do
1344
1398
  end
1345
1399
  end
1346
1400
  end
1401
+
1402
+ context 'when the id_sort option is none' do
1403
+
1404
+ let(:person) do
1405
+ Person.create
1406
+ end
1407
+
1408
+ let(:criteria) do
1409
+ Post.where(person_id: person.id)
1410
+ end
1411
+
1412
+ let(:enumerable) do
1413
+ described_class.new(criteria)
1414
+ end
1415
+
1416
+ let!(:first_post) do
1417
+ person.posts.create(title: "One")
1418
+ end
1419
+
1420
+ let!(:second_post) do
1421
+ person.posts.create(title: "Two")
1422
+ end
1423
+
1424
+ it 'does not use the sort on id' do
1425
+ expect(enumerable.last(id_sort: :none)).to eq(first_post)
1426
+ end
1427
+ end
1428
+
1429
+ context 'when the id_sort option is not provided' do
1430
+
1431
+ let(:person) do
1432
+ Person.create
1433
+ end
1434
+
1435
+ let(:criteria) do
1436
+ Post.where(person_id: person.id)
1437
+ end
1438
+
1439
+ let(:enumerable) do
1440
+ described_class.new(criteria)
1441
+ end
1442
+
1443
+ let!(:first_post) do
1444
+ person.posts.create(title: "One")
1445
+ end
1446
+
1447
+ let!(:second_post) do
1448
+ person.posts.create(title: "Two")
1449
+ end
1450
+
1451
+ it 'uses the sort on id' do
1452
+ expect(enumerable.last).to eq(second_post)
1453
+ end
1454
+ end
1347
1455
  end
1348
1456
 
1349
1457
  describe "#kind_of?" do