mongoid 4.0.0 → 4.0.1
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
- data/CHANGELOG.md +18 -1
- data/README.md +6 -2
- data/lib/config/locales/en.yml +2 -2
- data/lib/mongoid/atomic.rb +2 -2
- data/lib/mongoid/attributes.rb +2 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
- data/lib/mongoid/contextual/mongo.rb +3 -3
- data/lib/mongoid/criteria/#findable.rb# +141 -0
- data/lib/mongoid/document.rb +5 -5
- data/lib/mongoid/query_cache.rb +10 -2
- data/lib/mongoid/railtie.rb +2 -15
- data/lib/mongoid/railties/database.rake +1 -1
- data/lib/mongoid/relations/accessors.rb +2 -2
- data/lib/mongoid/relations/binding.rb +1 -1
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +1 -1
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +1 -1
- data/lib/mongoid/relations/counter_cache.rb +2 -2
- data/lib/mongoid/relations/one.rb +1 -1
- data/lib/mongoid/relations/referenced/many.rb +4 -4
- data/lib/mongoid/relations/referenced/many_to_many.rb +5 -5
- data/lib/mongoid/relations/synchronization.rb +4 -4
- data/lib/mongoid/relations/targets/enumerable.rb +10 -10
- data/lib/mongoid/reloadable.rb +3 -3
- data/lib/mongoid/threaded.rb +26 -15
- data/lib/mongoid/traversable.rb +6 -2
- data/lib/mongoid/validatable/uniqueness.rb +3 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
- data/spec/app/models/id_key.rb +6 -0
- data/spec/mongoid/#atomic_spec.rb# +365 -0
- data/spec/mongoid/attributes_spec.rb +36 -0
- data/spec/mongoid/contextual/atomic_spec.rb +7 -13
- data/spec/mongoid/criteria_spec.rb +86 -75
- data/spec/mongoid/document_spec.rb +2 -2
- data/spec/mongoid/findable_spec.rb +2 -2
- data/spec/mongoid/positional_spec.rb +5 -10
- data/spec/mongoid/query_cache_spec.rb +32 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +23 -0
- data/spec/mongoid/reloadable_spec.rb +23 -0
- data/spec/spec_helper.rb +2 -0
- metadata +7 -2
@@ -248,6 +248,17 @@ describe Mongoid::Attributes do
|
|
248
248
|
it "delegates to #id" do
|
249
249
|
expect(person._id).to eq(person.id)
|
250
250
|
end
|
251
|
+
|
252
|
+
context "when #id alias is overridden" do
|
253
|
+
|
254
|
+
let(:object) do
|
255
|
+
IdKey.new(key: 'foo')
|
256
|
+
end
|
257
|
+
|
258
|
+
it "delegates to another method" do
|
259
|
+
expect(object.id).to eq(object.key)
|
260
|
+
end
|
261
|
+
end
|
251
262
|
end
|
252
263
|
|
253
264
|
describe "#_id=" do
|
@@ -314,6 +325,19 @@ describe Mongoid::Attributes do
|
|
314
325
|
expect(person.id).to eq(2)
|
315
326
|
end
|
316
327
|
end
|
328
|
+
|
329
|
+
context "when #id= alias is overridden" do
|
330
|
+
|
331
|
+
let(:object) do
|
332
|
+
IdKey.new(key: 'foo')
|
333
|
+
end
|
334
|
+
|
335
|
+
it "delegates to another method" do
|
336
|
+
object.id = 'bar'
|
337
|
+
expect(object.id).to eq('bar')
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
317
341
|
end
|
318
342
|
|
319
343
|
context "when using string ids" do
|
@@ -853,6 +877,18 @@ describe Mongoid::Attributes do
|
|
853
877
|
expect(person.attribute_present?(:title)).to be false
|
854
878
|
end
|
855
879
|
end
|
880
|
+
|
881
|
+
context "when the attribute is not on only list" do
|
882
|
+
|
883
|
+
before { Person.create }
|
884
|
+
let(:person) do
|
885
|
+
Person.only(:id).first
|
886
|
+
end
|
887
|
+
|
888
|
+
it "return false" do
|
889
|
+
expect(person.attribute_present?(:foobar)).to be false
|
890
|
+
end
|
891
|
+
end
|
856
892
|
end
|
857
893
|
|
858
894
|
describe "#has_attribute?" do
|
@@ -103,10 +103,8 @@ describe Mongoid::Contextual::Atomic do
|
|
103
103
|
expect(depeche_mode.reload.likes).to eq(12)
|
104
104
|
end
|
105
105
|
|
106
|
-
|
107
|
-
|
108
|
-
expect(smiths.reload.likes).to eq(0)
|
109
|
-
end
|
106
|
+
it "does not error on non initialized fields" do
|
107
|
+
expect(smiths.reload.likes).to eq(0)
|
110
108
|
end
|
111
109
|
end
|
112
110
|
|
@@ -120,10 +118,8 @@ describe Mongoid::Contextual::Atomic do
|
|
120
118
|
expect(depeche_mode.reload.likes).to eq(61)
|
121
119
|
end
|
122
120
|
|
123
|
-
|
124
|
-
|
125
|
-
expect(smiths.reload.likes).to eq(13)
|
126
|
-
end
|
121
|
+
it "does not error on non initialized fields" do
|
122
|
+
expect(smiths.reload.likes).to eq(13)
|
127
123
|
end
|
128
124
|
end
|
129
125
|
|
@@ -137,13 +133,11 @@ describe Mongoid::Contextual::Atomic do
|
|
137
133
|
expect(depeche_mode.reload.likes).to eq(14)
|
138
134
|
end
|
139
135
|
|
140
|
-
|
141
|
-
|
142
|
-
expect(smiths.reload.likes).to eq(10)
|
143
|
-
end
|
136
|
+
it "does not error on non initialized fields" do
|
137
|
+
expect(smiths.reload.likes).to eq(10)
|
144
138
|
end
|
145
139
|
end
|
146
|
-
end
|
140
|
+
end if mongodb_version > "2.5"
|
147
141
|
|
148
142
|
describe "#inc" do
|
149
143
|
|
@@ -1371,6 +1371,77 @@ describe Mongoid::Criteria do
|
|
1371
1371
|
|
1372
1372
|
context "when including a belongs to relation" do
|
1373
1373
|
|
1374
|
+
context "when the criteria is from the root" do
|
1375
|
+
|
1376
|
+
let!(:person_two) do
|
1377
|
+
Person.create(age: 2)
|
1378
|
+
end
|
1379
|
+
|
1380
|
+
let!(:post_one) do
|
1381
|
+
person.posts.create(title: "one")
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
let!(:post_two) do
|
1385
|
+
person_two.posts.create(title: "two")
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
context "when calling first" do
|
1389
|
+
|
1390
|
+
let(:criteria) do
|
1391
|
+
Post.includes(:person)
|
1392
|
+
end
|
1393
|
+
|
1394
|
+
let!(:document) do
|
1395
|
+
criteria.first
|
1396
|
+
end
|
1397
|
+
|
1398
|
+
it "eager loads the first document" do
|
1399
|
+
expect_query(0) do
|
1400
|
+
expect(document.person).to eq(person)
|
1401
|
+
end
|
1402
|
+
end
|
1403
|
+
|
1404
|
+
it "does not eager load the last document" do
|
1405
|
+
doc = criteria.last
|
1406
|
+
expect_query(1) do
|
1407
|
+
expect(doc.person).to eq(person_two)
|
1408
|
+
end
|
1409
|
+
end
|
1410
|
+
|
1411
|
+
it "returns the first document" do
|
1412
|
+
expect(document).to eq(post_one)
|
1413
|
+
end
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
context "when calling last" do
|
1417
|
+
|
1418
|
+
let!(:criteria) do
|
1419
|
+
Post.includes(:person)
|
1420
|
+
end
|
1421
|
+
|
1422
|
+
let!(:document) do
|
1423
|
+
criteria.last
|
1424
|
+
end
|
1425
|
+
|
1426
|
+
it "eager loads the last document" do
|
1427
|
+
expect_query(0) do
|
1428
|
+
expect(document.person).to eq(person_two)
|
1429
|
+
end
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
it "does not eager load the first document" do
|
1433
|
+
doc = criteria.first
|
1434
|
+
expect_query(1) do
|
1435
|
+
expect(doc.person).to eq(person)
|
1436
|
+
end
|
1437
|
+
end
|
1438
|
+
|
1439
|
+
it "returns the last document" do
|
1440
|
+
expect(document).to eq(post_two)
|
1441
|
+
end
|
1442
|
+
end
|
1443
|
+
end
|
1444
|
+
|
1374
1445
|
context "when the criteria is from an embedded relation" do
|
1375
1446
|
|
1376
1447
|
let(:peep) do
|
@@ -1495,77 +1566,6 @@ describe Mongoid::Criteria do
|
|
1495
1566
|
end
|
1496
1567
|
end
|
1497
1568
|
end
|
1498
|
-
|
1499
|
-
context "when the criteria is from the root" do
|
1500
|
-
|
1501
|
-
let!(:person_two) do
|
1502
|
-
Person.create(age: 2)
|
1503
|
-
end
|
1504
|
-
|
1505
|
-
let!(:post_one) do
|
1506
|
-
person.posts.create(title: "one")
|
1507
|
-
end
|
1508
|
-
|
1509
|
-
let!(:post_two) do
|
1510
|
-
person_two.posts.create(title: "two")
|
1511
|
-
end
|
1512
|
-
|
1513
|
-
context "when calling first" do
|
1514
|
-
|
1515
|
-
let(:criteria) do
|
1516
|
-
Post.includes(:person)
|
1517
|
-
end
|
1518
|
-
|
1519
|
-
let!(:document) do
|
1520
|
-
criteria.first
|
1521
|
-
end
|
1522
|
-
|
1523
|
-
it "eager loads the first document" do
|
1524
|
-
expect_query(0) do
|
1525
|
-
expect(document.person).to eq(person)
|
1526
|
-
end
|
1527
|
-
end
|
1528
|
-
|
1529
|
-
it "does not eager load the last document" do
|
1530
|
-
doc = criteria.last
|
1531
|
-
expect_query(1) do
|
1532
|
-
expect(doc.person).to eq(person_two)
|
1533
|
-
end
|
1534
|
-
end
|
1535
|
-
|
1536
|
-
it "returns the first document" do
|
1537
|
-
expect(document).to eq(post_one)
|
1538
|
-
end
|
1539
|
-
end
|
1540
|
-
|
1541
|
-
context "when calling last" do
|
1542
|
-
|
1543
|
-
let!(:criteria) do
|
1544
|
-
Post.includes(:person)
|
1545
|
-
end
|
1546
|
-
|
1547
|
-
let!(:document) do
|
1548
|
-
criteria.last
|
1549
|
-
end
|
1550
|
-
|
1551
|
-
it "eager loads the last document" do
|
1552
|
-
expect_query(0) do
|
1553
|
-
expect(document.person).to eq(person_two)
|
1554
|
-
end
|
1555
|
-
end
|
1556
|
-
|
1557
|
-
it "does not eager load the first document" do
|
1558
|
-
doc = criteria.first
|
1559
|
-
expect_query(1) do
|
1560
|
-
expect(doc.person).to eq(person)
|
1561
|
-
end
|
1562
|
-
end
|
1563
|
-
|
1564
|
-
it "returns the last document" do
|
1565
|
-
expect(document).to eq(post_two)
|
1566
|
-
end
|
1567
|
-
end
|
1568
|
-
end
|
1569
1569
|
end
|
1570
1570
|
|
1571
1571
|
context "when providing inclusions to the default scope" do
|
@@ -2851,6 +2851,17 @@ describe Mongoid::Criteria do
|
|
2851
2851
|
end
|
2852
2852
|
end
|
2853
2853
|
|
2854
|
+
context "when plucking existent and non-existent fields" do
|
2855
|
+
|
2856
|
+
let(:plucked) do
|
2857
|
+
Band.all.pluck(:id, :fooz)
|
2858
|
+
end
|
2859
|
+
|
2860
|
+
it "returns nil for the field that doesnt exist" do
|
2861
|
+
expect(plucked).to eq([[depeche.id, nil], [tool.id, nil], [photek.id, nil] ])
|
2862
|
+
end
|
2863
|
+
end
|
2864
|
+
|
2854
2865
|
context "when plucking a field that doesnt exist" do
|
2855
2866
|
|
2856
2867
|
context "when pluck one field" do
|
@@ -2859,8 +2870,8 @@ describe Mongoid::Criteria do
|
|
2859
2870
|
Band.all.pluck(:foo)
|
2860
2871
|
end
|
2861
2872
|
|
2862
|
-
it "returns a
|
2863
|
-
expect(plucked).to eq([])
|
2873
|
+
it "returns a array with nil values" do
|
2874
|
+
expect(plucked).to eq([nil, nil, nil])
|
2864
2875
|
end
|
2865
2876
|
end
|
2866
2877
|
|
@@ -2870,8 +2881,8 @@ describe Mongoid::Criteria do
|
|
2870
2881
|
Band.all.pluck(:foo, :bar)
|
2871
2882
|
end
|
2872
2883
|
|
2873
|
-
it "returns a
|
2874
|
-
expect(plucked).to eq([[], [], []])
|
2884
|
+
it "returns a nil arrays" do
|
2885
|
+
expect(plucked).to eq([[nil, nil], [nil, nil], [nil, nil]])
|
2875
2886
|
end
|
2876
2887
|
end
|
2877
2888
|
end
|
@@ -144,7 +144,7 @@ describe Mongoid::Document do
|
|
144
144
|
context "with updated_at" do
|
145
145
|
|
146
146
|
let!(:updated_at) do
|
147
|
-
document.updated_at.utc.to_s(:
|
147
|
+
document.updated_at.utc.to_s(:nsec)
|
148
148
|
end
|
149
149
|
|
150
150
|
it "has the id and updated_at key name" do
|
@@ -182,7 +182,7 @@ describe Mongoid::Document do
|
|
182
182
|
end
|
183
183
|
|
184
184
|
let!(:updated_at) do
|
185
|
-
agent.updated_at.utc.to_s(:
|
185
|
+
agent.updated_at.utc.to_s(:nsec)
|
186
186
|
end
|
187
187
|
|
188
188
|
it "has the id and updated_at key name" do
|
@@ -15,8 +15,7 @@ describe Mongoid::Positional do
|
|
15
15
|
"$set" => {
|
16
16
|
"field" => "value",
|
17
17
|
"children.0.field" => "value",
|
18
|
-
"children.0.children.1.children.3.field" => "value"
|
19
|
-
"children.0.children.1.children.3.field" => "value",
|
18
|
+
"children.0.children.1.children.3.field" => "value"
|
20
19
|
},
|
21
20
|
"$pushAll" => {
|
22
21
|
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
@@ -113,8 +112,7 @@ describe Mongoid::Positional do
|
|
113
112
|
"$set" => {
|
114
113
|
"field" => "value",
|
115
114
|
"children.$.field" => "value",
|
116
|
-
"children.$.children.1.children.3.field" => "value"
|
117
|
-
"children.$.children.1.children.3.field" => "value",
|
115
|
+
"children.$.children.1.children.3.field" => "value"
|
118
116
|
},
|
119
117
|
"$pushAll" => {
|
120
118
|
"children.$.children.1.children.3.fields" => [ "value", "value" ]
|
@@ -142,8 +140,7 @@ describe Mongoid::Positional do
|
|
142
140
|
"$set" => {
|
143
141
|
"field" => "value",
|
144
142
|
"children.0.field" => "value",
|
145
|
-
"children.0.children.1.children.3.field" => "value"
|
146
|
-
"children.0.children.1.children.3.field" => "value",
|
143
|
+
"children.0.children.1.children.3.field" => "value"
|
147
144
|
},
|
148
145
|
"$pushAll" => {
|
149
146
|
"children.0.children.1.children.3.fields" => [ "value", "value" ]
|
@@ -172,8 +169,7 @@ describe Mongoid::Positional do
|
|
172
169
|
"$set" => {
|
173
170
|
"field" => "value",
|
174
171
|
"children.$.field" => "value",
|
175
|
-
"children.0.children.$.children.3.field" => "value"
|
176
|
-
"children.0.children.$.children.3.field" => "value",
|
172
|
+
"children.0.children.$.children.3.field" => "value"
|
177
173
|
},
|
178
174
|
"$pushAll" => {
|
179
175
|
"children.0.children.$.children.3.fields" => [ "value", "value" ]
|
@@ -206,8 +202,7 @@ describe Mongoid::Positional do
|
|
206
202
|
"$set" => {
|
207
203
|
"field" => "value",
|
208
204
|
"children.$.field" => "value",
|
209
|
-
"children.0.children.1.children.$.field" => "value"
|
210
|
-
"children.0.children.1.children.$.field" => "value",
|
205
|
+
"children.0.children.1.children.$.field" => "value"
|
211
206
|
},
|
212
207
|
"$pushAll" => {
|
213
208
|
"children.0.children.1.children.$.fields" => [ "value", "value" ]
|
@@ -177,6 +177,38 @@ describe Mongoid::QueryCache do
|
|
177
177
|
end
|
178
178
|
end
|
179
179
|
|
180
|
+
context "when querying a very large collection" do
|
181
|
+
|
182
|
+
before do
|
183
|
+
123.times { Band.create! }
|
184
|
+
end
|
185
|
+
|
186
|
+
it "returns the right number of records" do
|
187
|
+
expect(Band.all.to_a.length).to eq(123)
|
188
|
+
end
|
189
|
+
|
190
|
+
it "#pluck returns the same count of objects" do
|
191
|
+
expect(Band.pluck(:name).length).to eq(123)
|
192
|
+
end
|
193
|
+
|
194
|
+
context "when loading all the documents" do
|
195
|
+
|
196
|
+
before do
|
197
|
+
Band.all.to_a
|
198
|
+
end
|
199
|
+
|
200
|
+
it "caches the complete result of the query" do
|
201
|
+
expect_no_queries do
|
202
|
+
expect(Band.all.to_a.length).to eq(123)
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
it "returns the same count of objects when using #pluck" do
|
207
|
+
expect(Band.pluck(:name).length).to eq(123)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
180
212
|
context "when inserting an index" do
|
181
213
|
|
182
214
|
it "does not cache the query" do
|
@@ -3555,4 +3555,27 @@ describe Mongoid::Relations::Referenced::Many do
|
|
3555
3555
|
expect(person.posts.open).to eq([ post ])
|
3556
3556
|
end
|
3557
3557
|
end
|
3558
|
+
|
3559
|
+
context "when accessing a relation named parent" do
|
3560
|
+
let!(:parent) do
|
3561
|
+
Odd.create(name: "odd parent")
|
3562
|
+
end
|
3563
|
+
|
3564
|
+
let(:child) do
|
3565
|
+
Even.create(parent_id: parent.id, name: "original even child")
|
3566
|
+
end
|
3567
|
+
|
3568
|
+
it "updates the child after accessing the parent" do
|
3569
|
+
# Access parent relation on the child to make sure it is loaded
|
3570
|
+
child.parent
|
3571
|
+
|
3572
|
+
new_child_name = "updated even child"
|
3573
|
+
|
3574
|
+
child.name = new_child_name
|
3575
|
+
child.save!
|
3576
|
+
|
3577
|
+
reloaded = Even.find(child.id)
|
3578
|
+
expect(reloaded.name).to eq(new_child_name)
|
3579
|
+
end
|
3580
|
+
end
|
3558
3581
|
end
|
@@ -261,5 +261,28 @@ describe Mongoid::Reloadable do
|
|
261
261
|
end
|
262
262
|
end
|
263
263
|
end
|
264
|
+
|
265
|
+
context "when overriding #id alias" do
|
266
|
+
|
267
|
+
let!(:object) do
|
268
|
+
IdKey.create(key: 'foo')
|
269
|
+
end
|
270
|
+
|
271
|
+
let!(:from_db) do
|
272
|
+
IdKey.find(object._id).tap do |object|
|
273
|
+
object.key = 'bar'
|
274
|
+
object.save
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
it "reloads the object attributes from the db" do
|
279
|
+
object.reload
|
280
|
+
expect(object.key).to eq('bar')
|
281
|
+
end
|
282
|
+
|
283
|
+
it "reload should return self" do
|
284
|
+
expect(object.reload).to eq(from_db)
|
285
|
+
end
|
286
|
+
end
|
264
287
|
end
|
265
288
|
end
|