mongoid 5.1.5 → 5.2.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/config/locales/en.yml +15 -0
- data/lib/mongoid.rb +5 -0
- data/lib/mongoid/attributes/dynamic.rb +3 -3
- data/lib/mongoid/clients/factory.rb +2 -0
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +0 -1
- data/lib/mongoid/contextual/map_reduce.rb +20 -97
- data/lib/mongoid/contextual/memory.rb +1 -0
- data/lib/mongoid/contextual/mongo.rb +20 -15
- data/lib/mongoid/criteria.rb +2 -0
- data/lib/mongoid/document.rb +1 -0
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +20 -0
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/extensions/decimal128.rb +39 -0
- data/lib/mongoid/fields/localized.rb +8 -3
- data/lib/mongoid/indexable/validators/options.rb +2 -1
- data/lib/mongoid/persistable/deletable.rb +3 -7
- data/lib/mongoid/persistable/settable.rb +3 -1
- data/lib/mongoid/query_cache.rb +24 -2
- data/lib/mongoid/relations/accessors.rb +1 -1
- data/lib/mongoid/relations/builders.rb +2 -2
- data/lib/mongoid/relations/eager.rb +2 -2
- data/lib/mongoid/relations/reflections.rb +5 -3
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +6 -2
- data/spec/app/models/band.rb +1 -0
- data/spec/config/mongoid.yml +5 -0
- data/spec/mongoid/clients/factory_spec.rb +8 -0
- data/spec/mongoid/clients_spec.rb +78 -1
- data/spec/mongoid/config_spec.rb +31 -0
- data/spec/mongoid/contextual/atomic_spec.rb +342 -76
- data/spec/mongoid/contextual/map_reduce_spec.rb +111 -119
- data/spec/mongoid/contextual/memory_spec.rb +316 -56
- data/spec/mongoid/contextual/mongo_spec.rb +391 -11
- data/spec/mongoid/criteria_spec.rb +21 -2
- data/spec/mongoid/extensions/decimal128_spec.rb +44 -0
- data/spec/mongoid/extensions/time_spec.rb +2 -2
- data/spec/mongoid/fields/localized_spec.rb +91 -0
- data/spec/mongoid/indexable_spec.rb +44 -0
- data/spec/mongoid/persistable/settable_spec.rb +44 -0
- data/spec/mongoid/query_cache_spec.rb +86 -0
- data/spec/mongoid/relations/cyclic_spec.rb +22 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +11 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +11 -0
- data/spec/mongoid/relations/reflections_spec.rb +9 -9
- data/spec/mongoid/scopable_spec.rb +12 -0
- data/spec/spec_helper.rb +9 -0
- metadata +26 -16
- metadata.gz.sig +0 -0
@@ -167,6 +167,28 @@ describe Mongoid::Contextual::Mongo do
|
|
167
167
|
expect(count).to eq(2)
|
168
168
|
end
|
169
169
|
end
|
170
|
+
|
171
|
+
context 'when a collation is specified', if: collation_supported? do
|
172
|
+
|
173
|
+
let(:context) do
|
174
|
+
described_class.new(criteria)
|
175
|
+
end
|
176
|
+
|
177
|
+
context 'when the collation is specified on the criteria' do
|
178
|
+
|
179
|
+
let(:criteria) do
|
180
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
181
|
+
end
|
182
|
+
|
183
|
+
let(:count) do
|
184
|
+
context.count
|
185
|
+
end
|
186
|
+
|
187
|
+
it 'applies the collation' do
|
188
|
+
expect(count).to eq(1)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
170
192
|
end
|
171
193
|
|
172
194
|
[ :delete, :delete_all ].each do |method|
|
@@ -208,7 +230,34 @@ describe Mongoid::Contextual::Mongo do
|
|
208
230
|
end
|
209
231
|
end
|
210
232
|
|
211
|
-
context
|
233
|
+
context 'when the criteria has a collation', if: collation_supported? do
|
234
|
+
|
235
|
+
let(:criteria) do
|
236
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
237
|
+
end
|
238
|
+
|
239
|
+
let(:context) do
|
240
|
+
described_class.new(criteria)
|
241
|
+
end
|
242
|
+
|
243
|
+
let!(:deleted) do
|
244
|
+
context.send(method)
|
245
|
+
end
|
246
|
+
|
247
|
+
it "deletes the matching documents" do
|
248
|
+
expect(Band.find(new_order.id)).to eq(new_order)
|
249
|
+
end
|
250
|
+
|
251
|
+
it "deletes the correct number of documents" do
|
252
|
+
expect(Band.count).to eq(1)
|
253
|
+
end
|
254
|
+
|
255
|
+
it "returns the number of documents deleted" do
|
256
|
+
expect(deleted).to eq(1)
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
context "when the selector is not constraining" do
|
212
261
|
|
213
262
|
let(:criteria) do
|
214
263
|
Band.all
|
@@ -266,6 +315,33 @@ describe Mongoid::Contextual::Mongo do
|
|
266
315
|
it "returns the number of documents destroyed" do
|
267
316
|
expect(destroyed).to eq(1)
|
268
317
|
end
|
318
|
+
|
319
|
+
context 'when the criteria has a collation', if: collation_supported? do
|
320
|
+
|
321
|
+
let(:criteria) do
|
322
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
323
|
+
end
|
324
|
+
|
325
|
+
let(:context) do
|
326
|
+
described_class.new(criteria)
|
327
|
+
end
|
328
|
+
|
329
|
+
let!(:destroyed) do
|
330
|
+
context.send(method)
|
331
|
+
end
|
332
|
+
|
333
|
+
it "destroys the matching documents" do
|
334
|
+
expect(Band.find(new_order.id)).to eq(new_order)
|
335
|
+
end
|
336
|
+
|
337
|
+
it "destroys the correct number of documents" do
|
338
|
+
expect(Band.count).to eq(1)
|
339
|
+
end
|
340
|
+
|
341
|
+
it "returns the number of documents destroyed" do
|
342
|
+
expect(destroyed).to eq(1)
|
343
|
+
end
|
344
|
+
end
|
269
345
|
end
|
270
346
|
|
271
347
|
context "when the selector is not contraining" do
|
@@ -340,6 +416,29 @@ describe Mongoid::Contextual::Mongo do
|
|
340
416
|
expect(context.distinct(:years)).to eq([ 30, 25 ])
|
341
417
|
end
|
342
418
|
end
|
419
|
+
|
420
|
+
context 'when a collation is specified', if: collation_supported? do
|
421
|
+
|
422
|
+
before do
|
423
|
+
Band.create(name: 'DEPECHE MODE')
|
424
|
+
end
|
425
|
+
|
426
|
+
let(:context) do
|
427
|
+
described_class.new(criteria)
|
428
|
+
end
|
429
|
+
|
430
|
+
let(:expected_results) do
|
431
|
+
["Depeche Mode", "New Order"]
|
432
|
+
end
|
433
|
+
|
434
|
+
let(:criteria) do
|
435
|
+
Band.where({}).collation(locale: 'en_US', strength: 2)
|
436
|
+
end
|
437
|
+
|
438
|
+
it 'applies the collation' do
|
439
|
+
expect(context.distinct(:name)).to eq(expected_results)
|
440
|
+
end
|
441
|
+
end
|
343
442
|
end
|
344
443
|
|
345
444
|
describe "#each" do
|
@@ -356,6 +455,29 @@ describe Mongoid::Contextual::Mongo do
|
|
356
455
|
described_class.new(criteria)
|
357
456
|
end
|
358
457
|
|
458
|
+
context 'when the criteria has a collation', if: collation_supported? do
|
459
|
+
|
460
|
+
let(:criteria) do
|
461
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
462
|
+
end
|
463
|
+
|
464
|
+
it "yields mongoid documents to the block" do
|
465
|
+
context.each do |doc|
|
466
|
+
expect(doc).to be_a(Mongoid::Document)
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
it "iterates over the matching documents" do
|
471
|
+
context.each do |doc|
|
472
|
+
expect(doc.name).to eq("Depeche Mode")
|
473
|
+
end
|
474
|
+
end
|
475
|
+
|
476
|
+
it "returns self" do
|
477
|
+
expect(context.each{}).to be(context)
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
359
481
|
context "when providing a block" do
|
360
482
|
|
361
483
|
it "yields mongoid documents to the block" do
|
@@ -398,9 +520,22 @@ describe Mongoid::Contextual::Mongo do
|
|
398
520
|
|
399
521
|
context "when iterating with next" do
|
400
522
|
|
523
|
+
before do
|
524
|
+
10.times { |i| Band.create(name: "Test #{i}") }
|
525
|
+
end
|
526
|
+
|
527
|
+
let(:criteria) do
|
528
|
+
Band.batch_size(5)
|
529
|
+
end
|
530
|
+
|
401
531
|
it "yields mongoid documents" do
|
402
532
|
expect(enum.next).to be_a(Mongoid::Document)
|
403
533
|
end
|
534
|
+
|
535
|
+
it "does not load all documents" do
|
536
|
+
expect(Mongo::Logger.logger).to receive(:debug?).exactly(2).times.and_call_original
|
537
|
+
enum.next
|
538
|
+
end
|
404
539
|
end
|
405
540
|
end
|
406
541
|
end
|
@@ -542,6 +677,161 @@ describe Mongoid::Contextual::Mongo do
|
|
542
677
|
end
|
543
678
|
end
|
544
679
|
|
680
|
+
describe "#find_one_and_replace" do
|
681
|
+
|
682
|
+
let!(:depeche) do
|
683
|
+
Band.create(name: "Depeche Mode")
|
684
|
+
end
|
685
|
+
|
686
|
+
let!(:tool) do
|
687
|
+
Band.create(name: "Tool")
|
688
|
+
end
|
689
|
+
|
690
|
+
context "when the selector matches" do
|
691
|
+
|
692
|
+
context "when not providing options" do
|
693
|
+
|
694
|
+
let(:criteria) do
|
695
|
+
Band.where(name: "Depeche Mode")
|
696
|
+
end
|
697
|
+
|
698
|
+
let(:context) do
|
699
|
+
described_class.new(criteria)
|
700
|
+
end
|
701
|
+
|
702
|
+
let!(:result) do
|
703
|
+
context.find_one_and_replace(name: 'FKA Twigs')
|
704
|
+
end
|
705
|
+
|
706
|
+
it "returns the first matching document" do
|
707
|
+
expect(result).to eq(depeche)
|
708
|
+
end
|
709
|
+
|
710
|
+
it "updates the document in the database" do
|
711
|
+
expect(depeche.reload.name).to eq('FKA Twigs')
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
715
|
+
context "when sorting" do
|
716
|
+
|
717
|
+
let(:criteria) do
|
718
|
+
Band.desc(:name)
|
719
|
+
end
|
720
|
+
|
721
|
+
let(:context) do
|
722
|
+
described_class.new(criteria)
|
723
|
+
end
|
724
|
+
|
725
|
+
let!(:result) do
|
726
|
+
context.find_one_and_replace(likes: 1)
|
727
|
+
end
|
728
|
+
|
729
|
+
it "returns the first matching document" do
|
730
|
+
expect(result).to eq(tool)
|
731
|
+
end
|
732
|
+
|
733
|
+
it "updates the document in the database" do
|
734
|
+
expect(tool.reload.likes).to eq(1)
|
735
|
+
expect(tool.reload.name).to be_nil
|
736
|
+
end
|
737
|
+
end
|
738
|
+
|
739
|
+
context "when limiting fields" do
|
740
|
+
|
741
|
+
let(:criteria) do
|
742
|
+
Band.only(:_id)
|
743
|
+
end
|
744
|
+
|
745
|
+
let(:context) do
|
746
|
+
described_class.new(criteria)
|
747
|
+
end
|
748
|
+
|
749
|
+
let!(:result) do
|
750
|
+
context.find_one_and_replace(name: 'FKA Twigs', likes: 1)
|
751
|
+
end
|
752
|
+
|
753
|
+
it "returns the first matching document" do
|
754
|
+
expect(result).to eq(depeche)
|
755
|
+
end
|
756
|
+
|
757
|
+
it "limits the returned fields" do
|
758
|
+
expect(result.name).to be_nil
|
759
|
+
end
|
760
|
+
|
761
|
+
it "updates the document in the database" do
|
762
|
+
expect(depeche.reload.likes).to eq(1)
|
763
|
+
end
|
764
|
+
end
|
765
|
+
|
766
|
+
context "when returning new" do
|
767
|
+
|
768
|
+
let(:criteria) do
|
769
|
+
Band.where(name: "Depeche Mode")
|
770
|
+
end
|
771
|
+
|
772
|
+
let(:context) do
|
773
|
+
described_class.new(criteria)
|
774
|
+
end
|
775
|
+
|
776
|
+
let!(:result) do
|
777
|
+
context.find_one_and_replace({ likes: 1 }, return_document: :after)
|
778
|
+
end
|
779
|
+
|
780
|
+
it "returns the first matching document" do
|
781
|
+
expect(result).to eq(depeche)
|
782
|
+
end
|
783
|
+
|
784
|
+
it "returns the updated document" do
|
785
|
+
expect(result.name).to be_nil
|
786
|
+
expect(result.likes).to eq(1)
|
787
|
+
end
|
788
|
+
end
|
789
|
+
|
790
|
+
context 'when a collation is specified on the criteria', if: collation_supported? do
|
791
|
+
|
792
|
+
let(:criteria) do
|
793
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
794
|
+
end
|
795
|
+
|
796
|
+
let(:context) do
|
797
|
+
described_class.new(criteria)
|
798
|
+
end
|
799
|
+
|
800
|
+
let!(:result) do
|
801
|
+
context.find_one_and_replace({ likes: 1 }, return_document: :after)
|
802
|
+
end
|
803
|
+
|
804
|
+
it "returns the first matching document" do
|
805
|
+
expect(result).to eq(depeche)
|
806
|
+
end
|
807
|
+
|
808
|
+
it "returns the updated document" do
|
809
|
+
expect(result.likes).to eq(1)
|
810
|
+
expect(result.name).to be_nil
|
811
|
+
end
|
812
|
+
end
|
813
|
+
end
|
814
|
+
|
815
|
+
context "when the selector does not match" do
|
816
|
+
|
817
|
+
let(:criteria) do
|
818
|
+
Band.where(name: "DEPECHE MODE")
|
819
|
+
end
|
820
|
+
|
821
|
+
let(:context) do
|
822
|
+
described_class.new(criteria)
|
823
|
+
end
|
824
|
+
|
825
|
+
let(:result) do
|
826
|
+
context.find_one_and_replace(name: 'FKA Twigs')
|
827
|
+
end
|
828
|
+
|
829
|
+
it "returns nil" do
|
830
|
+
expect(result).to be_nil
|
831
|
+
end
|
832
|
+
end
|
833
|
+
end
|
834
|
+
|
545
835
|
describe "#find_one_and_update" do
|
546
836
|
|
547
837
|
let!(:depeche) do
|
@@ -650,10 +940,84 @@ describe Mongoid::Contextual::Mongo do
|
|
650
940
|
end
|
651
941
|
end
|
652
942
|
|
653
|
-
context
|
943
|
+
context 'when a collation is specified on the criteria', if: collation_supported? do
|
654
944
|
|
655
945
|
let(:criteria) do
|
656
|
-
Band.where(name: "
|
946
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
947
|
+
end
|
948
|
+
|
949
|
+
let(:context) do
|
950
|
+
described_class.new(criteria)
|
951
|
+
end
|
952
|
+
|
953
|
+
let!(:result) do
|
954
|
+
context.find_one_and_update({ "$inc" => { likes: 1 }}, return_document: :after)
|
955
|
+
end
|
956
|
+
|
957
|
+
it "returns the first matching document" do
|
958
|
+
expect(result).to eq(depeche)
|
959
|
+
end
|
960
|
+
|
961
|
+
it "returns the updated document" do
|
962
|
+
expect(result.likes).to eq(1)
|
963
|
+
end
|
964
|
+
end
|
965
|
+
end
|
966
|
+
|
967
|
+
context "when the selector does not match" do
|
968
|
+
|
969
|
+
let(:criteria) do
|
970
|
+
Band.where(name: "Placebo")
|
971
|
+
end
|
972
|
+
|
973
|
+
let(:context) do
|
974
|
+
described_class.new(criteria)
|
975
|
+
end
|
976
|
+
|
977
|
+
let(:result) do
|
978
|
+
context.find_one_and_update("$inc" => { likes: 1 })
|
979
|
+
end
|
980
|
+
|
981
|
+
it "returns nil" do
|
982
|
+
expect(result).to be_nil
|
983
|
+
end
|
984
|
+
end
|
985
|
+
end
|
986
|
+
|
987
|
+
describe "#find_one_and_delete" do
|
988
|
+
|
989
|
+
let!(:depeche) do
|
990
|
+
Band.create(name: "Depeche Mode")
|
991
|
+
end
|
992
|
+
|
993
|
+
let(:criteria) do
|
994
|
+
Band.where(name: "Depeche Mode")
|
995
|
+
end
|
996
|
+
|
997
|
+
let(:context) do
|
998
|
+
described_class.new(criteria)
|
999
|
+
end
|
1000
|
+
|
1001
|
+
let!(:result) do
|
1002
|
+
context.find_one_and_delete
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
context 'when the selector matches a document' do
|
1006
|
+
|
1007
|
+
it "returns the first matching document" do
|
1008
|
+
expect(result).to eq(depeche)
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
it "deletes the document from the database" do
|
1012
|
+
expect {
|
1013
|
+
depeche.reload
|
1014
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
1015
|
+
end
|
1016
|
+
|
1017
|
+
context 'when a collation is specified on the criteria', if: collation_supported? do
|
1018
|
+
|
1019
|
+
let(:criteria) do
|
1020
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
657
1021
|
end
|
658
1022
|
|
659
1023
|
let(:context) do
|
@@ -676,7 +1040,7 @@ describe Mongoid::Contextual::Mongo do
|
|
676
1040
|
end
|
677
1041
|
end
|
678
1042
|
|
679
|
-
context
|
1043
|
+
context 'when the selector does not match a document' do
|
680
1044
|
|
681
1045
|
let(:criteria) do
|
682
1046
|
Band.where(name: "Placebo")
|
@@ -687,7 +1051,7 @@ describe Mongoid::Contextual::Mongo do
|
|
687
1051
|
end
|
688
1052
|
|
689
1053
|
let(:result) do
|
690
|
-
context.
|
1054
|
+
context.find_one_and_delete
|
691
1055
|
end
|
692
1056
|
|
693
1057
|
it "returns nil" do
|
@@ -721,6 +1085,17 @@ describe Mongoid::Contextual::Mongo do
|
|
721
1085
|
it "returns the first matching document" do
|
722
1086
|
expect(context.send(method)).to eq(depeche_mode)
|
723
1087
|
end
|
1088
|
+
|
1089
|
+
context 'when the criteria has a collation', if: collation_supported? do
|
1090
|
+
|
1091
|
+
let(:criteria) do
|
1092
|
+
Band.where(name: "DEPECHE MODE").collation(locale: 'en_US', strength: 2)
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
it "returns the first matching document" do
|
1096
|
+
expect(context.send(method)).to eq(depeche_mode)
|
1097
|
+
end
|
1098
|
+
end
|
724
1099
|
end
|
725
1100
|
|
726
1101
|
context "when using .desc" do
|
@@ -1715,26 +2090,31 @@ describe Mongoid::Contextual::Mongo do
|
|
1715
2090
|
|
1716
2091
|
describe '#pipeline' do
|
1717
2092
|
|
1718
|
-
context 'when the criteria has a selector' do
|
2093
|
+
context 'when the criteria has a selector', if: non_legacy_server? do
|
2094
|
+
|
2095
|
+
before do
|
2096
|
+
Artist.index(name: "text")
|
2097
|
+
Artist.create_indexes
|
2098
|
+
end
|
1719
2099
|
|
1720
2100
|
let(:criteria) do
|
1721
|
-
|
2101
|
+
Artist.text_search("New Order")
|
1722
2102
|
end
|
1723
2103
|
|
1724
2104
|
let(:context) do
|
1725
2105
|
described_class.new(criteria)
|
1726
2106
|
end
|
1727
2107
|
|
1728
|
-
let(:
|
1729
|
-
context.send(:pipeline,
|
2108
|
+
let(:pipeline_match) do
|
2109
|
+
context.send(:pipeline, :some_field).first['$match']
|
1730
2110
|
end
|
1731
2111
|
|
1732
2112
|
it 'creates a pipeline with the selector as one of the $match criteria' do
|
1733
|
-
expect(
|
2113
|
+
expect(pipeline_match).to include({ :'$text' => { :'$search' => "New Order" } })
|
1734
2114
|
end
|
1735
2115
|
|
1736
2116
|
it 'creates a pipeline with the $exists operator as one of the $match criteria' do
|
1737
|
-
expect(
|
2117
|
+
expect(pipeline_match).to include({ 'some_field' => { '$exists' => true } })
|
1738
2118
|
end
|
1739
2119
|
end
|
1740
2120
|
end
|