mongoid 4.0.0 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|