mongoid 4.0.0.alpha2 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +55 -0
- data/README.md +3 -3
- data/lib/config/locales/en.yml +13 -0
- data/lib/mongoid.rb +3 -1
- data/lib/mongoid/atomic.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
- data/lib/mongoid/attributes.rb +23 -1
- data/lib/mongoid/attributes/processing.rb +1 -1
- data/lib/mongoid/composable.rb +3 -2
- data/lib/mongoid/contextual/command.rb +0 -26
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/mongo.rb +6 -29
- data/lib/mongoid/contextual/text_search.rb +3 -5
- data/lib/mongoid/criteria.rb +1 -1
- data/lib/mongoid/criteria/modifiable.rb +27 -7
- data/lib/mongoid/criteria/permission.rb +70 -0
- data/lib/mongoid/document.rb +5 -6
- data/lib/mongoid/errors.rb +2 -0
- data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
- data/lib/mongoid/errors/readonly_document.rb +24 -0
- data/lib/mongoid/extensions/boolean.rb +1 -0
- data/lib/mongoid/extensions/hash.rb +1 -1
- data/lib/mongoid/factory.rb +5 -3
- data/lib/mongoid/fields.rb +32 -0
- data/lib/mongoid/fields/localized.rb +1 -1
- data/lib/mongoid/fields/standard.rb +1 -1
- data/lib/mongoid/findable.rb +1 -0
- data/lib/mongoid/interceptable.rb +11 -6
- data/lib/mongoid/log_subscriber.rb +34 -1
- data/lib/mongoid/persistable/deletable.rb +1 -0
- data/lib/mongoid/persistable/destroyable.rb +7 -2
- data/lib/mongoid/persistable/updatable.rb +27 -26
- data/lib/mongoid/query_cache.rb +246 -0
- data/lib/mongoid/railties/database.rake +4 -26
- data/lib/mongoid/relations.rb +8 -22
- data/lib/mongoid/relations/accessors.rb +0 -3
- data/lib/mongoid/relations/binding.rb +1 -1
- data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
- data/lib/mongoid/relations/eager.rb +5 -6
- data/lib/mongoid/relations/eager/base.rb +97 -5
- data/lib/mongoid/relations/eager/belongs_to.rb +1 -0
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +16 -9
- data/lib/mongoid/relations/eager/has_many.rb +1 -0
- data/lib/mongoid/relations/eager/has_one.rb +1 -0
- data/lib/mongoid/relations/embedded/batchable.rb +1 -1
- data/lib/mongoid/relations/embedded/in.rb +4 -4
- data/lib/mongoid/relations/embedded/many.rb +7 -5
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/macros.rb +1 -0
- data/lib/mongoid/relations/marshalable.rb +3 -3
- data/lib/mongoid/relations/proxy.rb +12 -10
- data/lib/mongoid/relations/referenced/in.rb +2 -2
- data/lib/mongoid/relations/referenced/many.rb +9 -9
- data/lib/mongoid/relations/referenced/many_to_many.rb +7 -7
- data/lib/mongoid/relations/referenced/one.rb +4 -4
- data/lib/mongoid/{state.rb → stateful.rb} +13 -1
- data/lib/mongoid/tasks/database.rake +31 -0
- data/lib/mongoid/tasks/database.rb +107 -0
- data/lib/mongoid/threaded.rb +0 -47
- data/lib/mongoid/validatable/uniqueness.rb +4 -16
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +0 -3
- data/lib/rails/mongoid.rb +0 -124
- data/spec/app/models/edit.rb +5 -0
- data/spec/app/models/even.rb +7 -0
- data/spec/app/models/line_item.rb +1 -1
- data/spec/app/models/note.rb +2 -0
- data/spec/app/models/odd.rb +7 -0
- data/spec/app/models/record.rb +5 -0
- data/spec/app/models/wiki_page.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +76 -1
- data/spec/mongoid/changeable_spec.rb +6 -2
- data/spec/mongoid/contextual/mongo_spec.rb +3 -1
- data/spec/mongoid/contextual/text_search_spec.rb +3 -1
- data/spec/mongoid/criteria/modifiable_spec.rb +192 -0
- data/spec/mongoid/criteria_spec.rb +6 -2
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
- data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
- data/spec/mongoid/fields/localized_spec.rb +15 -0
- data/spec/mongoid/fields_spec.rb +88 -2
- data/spec/mongoid/log_subscriber_spec.rb +3 -3
- data/spec/mongoid/persistable/deletable_spec.rb +14 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +45 -1
- data/spec/mongoid/persistable/savable_spec.rb +34 -5
- data/spec/mongoid/query_cache_spec.rb +197 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +2 -2
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +1 -1
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +11 -37
- data/spec/mongoid/relations/eager/has_one_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/in_spec.rb +1 -1
- data/spec/mongoid/relations/embedded/many_spec.rb +10 -10
- data/spec/mongoid/relations/embedded/one_spec.rb +10 -2
- data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +37 -2
- data/spec/mongoid/relations/touchable_spec.rb +20 -0
- data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +26 -1
- data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
- data/spec/mongoid/tasks/database_spec.rb +148 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +7 -0
- data/spec/rails/mongoid_spec.rb +0 -316
- data/spec/spec_helper.rb +1 -0
- metadata +30 -8
@@ -14,6 +14,39 @@ describe Mongoid::Attributes do
|
|
14
14
|
expect(account.overridden).to eq("not recommended")
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
context "when the attribute was excluded in a criteria" do
|
19
|
+
|
20
|
+
let!(:person) do
|
21
|
+
Person.create(title: "sir")
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when excluding with only" do
|
25
|
+
|
26
|
+
let(:from_db) do
|
27
|
+
Person.only(:_id).first
|
28
|
+
end
|
29
|
+
|
30
|
+
it "raises an error" do
|
31
|
+
expect {
|
32
|
+
from_db.title
|
33
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when excluding with without" do
|
38
|
+
|
39
|
+
let(:from_db) do
|
40
|
+
Person.without(:title).first
|
41
|
+
end
|
42
|
+
|
43
|
+
it "raises an error" do
|
44
|
+
expect {
|
45
|
+
from_db.title
|
46
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
17
50
|
end
|
18
51
|
|
19
52
|
describe "#[]" do
|
@@ -70,6 +103,35 @@ describe Mongoid::Attributes do
|
|
70
103
|
Person.create(title: "sir")
|
71
104
|
end
|
72
105
|
|
106
|
+
context "when the attribute was excluded in a criteria" do
|
107
|
+
|
108
|
+
context "when excluding with only" do
|
109
|
+
|
110
|
+
let(:from_db) do
|
111
|
+
Person.only(:_id).first
|
112
|
+
end
|
113
|
+
|
114
|
+
it "raises an error" do
|
115
|
+
expect {
|
116
|
+
from_db[:title]
|
117
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
context "when excluding with without" do
|
122
|
+
|
123
|
+
let(:from_db) do
|
124
|
+
Person.without(:title).first
|
125
|
+
end
|
126
|
+
|
127
|
+
it "raises an error" do
|
128
|
+
expect {
|
129
|
+
from_db[:title]
|
130
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
73
135
|
context "when the attribute does not exist" do
|
74
136
|
|
75
137
|
before do
|
@@ -547,6 +609,19 @@ describe Mongoid::Attributes do
|
|
547
609
|
expect(person.map).to eq({})
|
548
610
|
end
|
549
611
|
end
|
612
|
+
|
613
|
+
context "when providing tainted parameters" do
|
614
|
+
|
615
|
+
let(:params) do
|
616
|
+
ActionController::Parameters.new(title: "sir")
|
617
|
+
end
|
618
|
+
|
619
|
+
it "raises an error" do
|
620
|
+
expect {
|
621
|
+
Person.new(params)
|
622
|
+
}.to raise_error(ActiveModel::ForbiddenAttributesError)
|
623
|
+
end
|
624
|
+
end
|
550
625
|
end
|
551
626
|
|
552
627
|
context "updating when attributes already exist" do
|
@@ -637,6 +712,7 @@ describe Mongoid::Attributes do
|
|
637
712
|
end
|
638
713
|
|
639
714
|
describe "#read_attribute_before_type_cast" do
|
715
|
+
|
640
716
|
let(:person) do
|
641
717
|
Person.create
|
642
718
|
end
|
@@ -657,7 +733,6 @@ describe Mongoid::Attributes do
|
|
657
733
|
end
|
658
734
|
end
|
659
735
|
|
660
|
-
|
661
736
|
describe "#attribute_present?" do
|
662
737
|
|
663
738
|
context "when document is a new record" do
|
@@ -1424,8 +1424,10 @@ describe Mongoid::Changeable do
|
|
1424
1424
|
end
|
1425
1425
|
|
1426
1426
|
after do
|
1427
|
-
Acolyte._save_callbacks.
|
1427
|
+
Acolyte._save_callbacks.select do |callback|
|
1428
1428
|
callback.kind == :after
|
1429
|
+
end.each do |callback|
|
1430
|
+
Acolyte._save_callbacks.delete(callback)
|
1429
1431
|
end
|
1430
1432
|
end
|
1431
1433
|
|
@@ -1448,8 +1450,10 @@ describe Mongoid::Changeable do
|
|
1448
1450
|
end
|
1449
1451
|
|
1450
1452
|
after do
|
1451
|
-
Acolyte._save_callbacks.
|
1453
|
+
Acolyte._save_callbacks.select do |callback|
|
1452
1454
|
callback.kind == :after
|
1455
|
+
end.each do |callback|
|
1456
|
+
Acolyte._save_callbacks.delete(callback)
|
1453
1457
|
end
|
1454
1458
|
end
|
1455
1459
|
|
@@ -1548,7 +1548,9 @@ describe Mongoid::Contextual::Mongo do
|
|
1548
1548
|
end
|
1549
1549
|
|
1550
1550
|
it "limits the fields to the projection" do
|
1551
|
-
expect
|
1551
|
+
expect {
|
1552
|
+
documents.first.origin
|
1553
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
1552
1554
|
end
|
1553
1555
|
end
|
1554
1556
|
|
@@ -298,6 +298,157 @@ describe Mongoid::Criteria::Modifiable do
|
|
298
298
|
end
|
299
299
|
end
|
300
300
|
|
301
|
+
describe ".find_or_create_by!" do
|
302
|
+
|
303
|
+
context "when the document is found" do
|
304
|
+
|
305
|
+
context "when providing an attribute" do
|
306
|
+
|
307
|
+
let!(:person) do
|
308
|
+
Person.create(title: "Senior")
|
309
|
+
end
|
310
|
+
|
311
|
+
it "returns the document" do
|
312
|
+
expect(Person.find_or_create_by!(title: "Senior")).to eq(person)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
context "when providing a document" do
|
317
|
+
|
318
|
+
context "with an owner with a BSON identity type" do
|
319
|
+
|
320
|
+
let!(:person) do
|
321
|
+
Person.create
|
322
|
+
end
|
323
|
+
|
324
|
+
let!(:game) do
|
325
|
+
Game.create(person: person)
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when providing the object directly" do
|
329
|
+
|
330
|
+
let(:from_db) do
|
331
|
+
Game.find_or_create_by!(person: person)
|
332
|
+
end
|
333
|
+
|
334
|
+
it "returns the document" do
|
335
|
+
expect(from_db).to eq(game)
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
context "when providing the proxy relation" do
|
340
|
+
|
341
|
+
let(:from_db) do
|
342
|
+
Game.find_or_create_by!(person: game.person)
|
343
|
+
end
|
344
|
+
|
345
|
+
it "returns the document" do
|
346
|
+
expect(from_db).to eq(game)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
context "with an owner with an Integer identity type" do
|
352
|
+
|
353
|
+
let!(:jar) do
|
354
|
+
Jar.create
|
355
|
+
end
|
356
|
+
|
357
|
+
let!(:cookie) do
|
358
|
+
Cookie.create(jar: jar)
|
359
|
+
end
|
360
|
+
|
361
|
+
let(:from_db) do
|
362
|
+
Cookie.find_or_create_by!(jar: jar)
|
363
|
+
end
|
364
|
+
|
365
|
+
it "returns the document" do
|
366
|
+
expect(from_db).to eq(cookie)
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
context "when the document is not found" do
|
373
|
+
|
374
|
+
context "when providing a document" do
|
375
|
+
|
376
|
+
let!(:person) do
|
377
|
+
Person.create
|
378
|
+
end
|
379
|
+
|
380
|
+
let!(:game) do
|
381
|
+
Game.create
|
382
|
+
end
|
383
|
+
|
384
|
+
let(:from_db) do
|
385
|
+
Game.find_or_create_by!(person: person)
|
386
|
+
end
|
387
|
+
|
388
|
+
it "returns the new document" do
|
389
|
+
expect(from_db.person).to eq(person)
|
390
|
+
end
|
391
|
+
|
392
|
+
it "does not return an existing false document" do
|
393
|
+
expect(from_db).to_not eq(game)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
context "when not providing a block" do
|
398
|
+
|
399
|
+
let!(:person) do
|
400
|
+
Person.find_or_create_by!(title: "Senorita")
|
401
|
+
end
|
402
|
+
|
403
|
+
it "creates a persisted document" do
|
404
|
+
expect(person).to be_persisted
|
405
|
+
end
|
406
|
+
|
407
|
+
it "sets the attributes" do
|
408
|
+
expect(person.title).to eq("Senorita")
|
409
|
+
end
|
410
|
+
end
|
411
|
+
|
412
|
+
context "when validation fails" do
|
413
|
+
|
414
|
+
before do
|
415
|
+
Person.validates_presence_of(:title)
|
416
|
+
end
|
417
|
+
|
418
|
+
after do
|
419
|
+
Person.reset_callbacks(:validate)
|
420
|
+
end
|
421
|
+
|
422
|
+
it "raises an exception" do
|
423
|
+
expect {
|
424
|
+
Person.find_or_create_by!(ssn: "test")
|
425
|
+
}.to raise_error(Mongoid::Errors::Validations)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
context "when providing a block" do
|
430
|
+
|
431
|
+
let!(:person) do
|
432
|
+
Person.find_or_create_by!(title: "Senorita") do |person|
|
433
|
+
person.pets = true
|
434
|
+
end
|
435
|
+
end
|
436
|
+
|
437
|
+
it "creates a persisted document" do
|
438
|
+
expect(person).to be_persisted
|
439
|
+
end
|
440
|
+
|
441
|
+
it "sets the attributes" do
|
442
|
+
expect(person.title).to eq("Senorita")
|
443
|
+
end
|
444
|
+
|
445
|
+
it "calls the block" do
|
446
|
+
expect(person.pets).to be true
|
447
|
+
end
|
448
|
+
end
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
301
452
|
describe ".find_or_initialize_by" do
|
302
453
|
|
303
454
|
context "when the document is found" do
|
@@ -404,6 +555,25 @@ describe Mongoid::Criteria::Modifiable do
|
|
404
555
|
end
|
405
556
|
end
|
406
557
|
|
558
|
+
context "when the criteria is on an embedded relation" do
|
559
|
+
|
560
|
+
let!(:band) do
|
561
|
+
Band.create(name: "Placebo")
|
562
|
+
end
|
563
|
+
|
564
|
+
let(:document) do
|
565
|
+
band.notes.permanent.first_or_create(text: "test")
|
566
|
+
end
|
567
|
+
|
568
|
+
it "returns a new document" do
|
569
|
+
expect(document.text).to eq("test")
|
570
|
+
end
|
571
|
+
|
572
|
+
it "returns a persisted document" do
|
573
|
+
expect(document).to be_persisted
|
574
|
+
end
|
575
|
+
end
|
576
|
+
|
407
577
|
context "when a block is provided" do
|
408
578
|
|
409
579
|
let(:document) do
|
@@ -1059,5 +1229,27 @@ describe Mongoid::Criteria::Modifiable do
|
|
1059
1229
|
end
|
1060
1230
|
end
|
1061
1231
|
end
|
1232
|
+
|
1233
|
+
context "when update document structure" do
|
1234
|
+
|
1235
|
+
before do
|
1236
|
+
person = Person.new(username: "user_title", score: 25)
|
1237
|
+
person.save
|
1238
|
+
end
|
1239
|
+
|
1240
|
+
let(:from_db) do
|
1241
|
+
Person.last
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
it "rename document string field" do
|
1245
|
+
Person.where(username: "user_title").update_all("$rename" => { username: "title" })
|
1246
|
+
expect(from_db.title).to eq("user_title")
|
1247
|
+
end
|
1248
|
+
|
1249
|
+
it "rename document integer field" do
|
1250
|
+
Person.where(score: 25).update_all("$rename" => { score: "age" })
|
1251
|
+
expect(from_db.age).to eq( 25 )
|
1252
|
+
end
|
1253
|
+
end
|
1062
1254
|
end
|
1063
1255
|
end
|
@@ -2611,7 +2611,9 @@ describe Mongoid::Criteria do
|
|
2611
2611
|
end
|
2612
2612
|
|
2613
2613
|
it "limits the returned fields" do
|
2614
|
-
expect
|
2614
|
+
expect {
|
2615
|
+
criteria.first.name
|
2616
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
2615
2617
|
end
|
2616
2618
|
|
2617
2619
|
it "does not add _type to the fields" do
|
@@ -2630,7 +2632,9 @@ describe Mongoid::Criteria do
|
|
2630
2632
|
end
|
2631
2633
|
|
2632
2634
|
it "excludes the non included fields" do
|
2633
|
-
expect
|
2635
|
+
expect {
|
2636
|
+
criteria.first.active
|
2637
|
+
}.to raise_error(ActiveModel::MissingAttributeError)
|
2634
2638
|
end
|
2635
2639
|
|
2636
2640
|
it "does not add _type to the fields" do
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Errors::DocumentNotDestroyed do
|
4
|
+
|
5
|
+
describe "#message" do
|
6
|
+
|
7
|
+
let(:post) do
|
8
|
+
Post.new
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:error) do
|
12
|
+
described_class.new(post.id, Post)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "contains the problem in the message" do
|
16
|
+
expect(error.message).to include(
|
17
|
+
"Post with id #{post.id.inspect} was not destroyed"
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "contains the summary in the message" do
|
22
|
+
expect(error.message).to include(
|
23
|
+
"When calling Post#destroy! and a callback halts the destroy callback"
|
24
|
+
)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "contains the resolution in the message" do
|
28
|
+
expect(error.message).to include(
|
29
|
+
"Check the before/after destroy callbacks to ensure"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Errors::ReadonlyDocument do
|
4
|
+
|
5
|
+
describe "#message" do
|
6
|
+
|
7
|
+
let(:error) do
|
8
|
+
described_class.new(Band)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "contains the problem in the message" do
|
12
|
+
expect(error.message).to include(
|
13
|
+
"Attempted to persist the readonly document 'Band'."
|
14
|
+
)
|
15
|
+
end
|
16
|
+
|
17
|
+
it "contains the summary in the message" do
|
18
|
+
expect(error.message).to include(
|
19
|
+
"Documents loaded from the database using #only"
|
20
|
+
)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "contains the resolution in the message" do
|
24
|
+
expect(error.message).to include(
|
25
|
+
"Don't attempt to persist documents that are flagged as readonly."
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|