mongoid 4.0.0.alpha2 → 4.0.0.beta1
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 +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
|