mongoid 5.0.0 → 5.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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -0
  4. data/CHANGELOG.md +54 -2
  5. data/lib/config/locales/en.yml +1 -1
  6. data/lib/mongoid/attributes.rb +1 -1
  7. data/lib/mongoid/clients.rb +7 -4
  8. data/lib/mongoid/clients/options.rb +2 -2
  9. data/lib/mongoid/contextual/aggregable/mongo.rb +2 -1
  10. data/lib/mongoid/contextual/geo_near.rb +1 -1
  11. data/lib/mongoid/contextual/memory.rb +4 -1
  12. data/lib/mongoid/contextual/mongo.rb +4 -5
  13. data/lib/mongoid/document.rb +1 -0
  14. data/lib/mongoid/indexable/specification.rb +3 -5
  15. data/lib/mongoid/indexable/validators/options.rb +7 -1
  16. data/lib/mongoid/matchable/exists.rb +1 -1
  17. data/lib/mongoid/persistable.rb +2 -1
  18. data/lib/mongoid/persistable/creatable.rb +1 -1
  19. data/lib/mongoid/persistable/deletable.rb +1 -1
  20. data/lib/mongoid/persistable/updatable.rb +2 -2
  21. data/lib/mongoid/positional.rb +75 -0
  22. data/lib/mongoid/relations/counter_cache.rb +19 -0
  23. data/lib/mongoid/relations/eager/base.rb +4 -2
  24. data/lib/mongoid/relations/embedded/batchable.rb +10 -3
  25. data/lib/mongoid/relations/proxy.rb +1 -1
  26. data/lib/mongoid/relations/touchable.rb +1 -1
  27. data/lib/mongoid/scopable.rb +6 -5
  28. data/lib/mongoid/selectable.rb +36 -1
  29. data/lib/mongoid/threaded.rb +34 -2
  30. data/lib/mongoid/timestamps/created.rb +1 -2
  31. data/lib/mongoid/timestamps/timeless.rb +19 -2
  32. data/lib/mongoid/timestamps/updated.rb +1 -1
  33. data/lib/mongoid/traversable.rb +1 -1
  34. data/lib/mongoid/version.rb +1 -1
  35. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -1
  36. data/spec/app/models/account.rb +8 -0
  37. data/spec/app/models/answer.rb +2 -0
  38. data/spec/app/models/article.rb +2 -0
  39. data/spec/app/models/author.rb +2 -0
  40. data/spec/app/models/baby.rb +4 -0
  41. data/spec/app/models/book.rb +2 -0
  42. data/spec/app/models/consumption_period.rb +7 -0
  43. data/spec/app/models/exhibitor.rb +1 -0
  44. data/spec/app/models/kaleidoscope.rb +6 -0
  45. data/spec/app/models/kangaroo.rb +4 -0
  46. data/spec/app/models/note.rb +3 -0
  47. data/spec/app/models/page.rb +11 -0
  48. data/spec/app/models/simple.rb +5 -0
  49. data/spec/config/mongoid.yml +3 -1
  50. data/spec/mongoid/atomic/paths_spec.rb +17 -10
  51. data/spec/mongoid/attributes_spec.rb +2 -2
  52. data/spec/mongoid/clients/options_spec.rb +15 -0
  53. data/spec/mongoid/clients_spec.rb +6 -2
  54. data/spec/mongoid/config_spec.rb +3 -2
  55. data/spec/mongoid/contextual/aggregable/mongo_spec.rb +25 -2
  56. data/spec/mongoid/contextual/atomic_spec.rb +6 -6
  57. data/spec/mongoid/contextual/mongo_spec.rb +28 -75
  58. data/spec/mongoid/criteria_spec.rb +54 -0
  59. data/spec/mongoid/fields/standard_spec.rb +1 -1
  60. data/spec/mongoid/fields_spec.rb +1 -1
  61. data/spec/mongoid/indexable/specification_spec.rb +1 -1
  62. data/spec/mongoid/indexable_spec.rb +7 -7
  63. data/spec/mongoid/interceptable_spec.rb +55 -0
  64. data/spec/mongoid/persistable/creatable_spec.rb +19 -0
  65. data/spec/mongoid/persistable/destroyable_spec.rb +50 -0
  66. data/spec/mongoid/persistable/incrementable_spec.rb +56 -4
  67. data/spec/mongoid/persistable/pushable_spec.rb +11 -0
  68. data/spec/mongoid/persistable/savable_spec.rb +20 -2
  69. data/spec/mongoid/positional_spec.rb +221 -0
  70. data/spec/mongoid/query_cache_spec.rb +19 -0
  71. data/spec/mongoid/relations/auto_save_spec.rb +1 -1
  72. data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +1 -1
  73. data/spec/mongoid/relations/counter_cache_spec.rb +64 -11
  74. data/spec/mongoid/relations/eager/has_many_spec.rb +37 -0
  75. data/spec/mongoid/relations/eager_spec.rb +11 -0
  76. data/spec/mongoid/relations/embedded/many_spec.rb +38 -9
  77. data/spec/mongoid/relations/embedded/one_spec.rb +1 -1
  78. data/spec/mongoid/relations/proxy_spec.rb +22 -0
  79. data/spec/mongoid/relations/reflections_spec.rb +1 -1
  80. data/spec/mongoid/scopable_spec.rb +160 -19
  81. data/spec/mongoid/selectable_spec.rb +16 -6
  82. data/spec/mongoid/timestamps/timeless_spec.rb +17 -0
  83. data/spec/mongoid/validatable/uniqueness_spec.rb +17 -0
  84. metadata +40 -5
  85. metadata.gz.sig +3 -0
@@ -1465,7 +1465,7 @@ describe Mongoid::Attributes do
1465
1465
  expect(product.cost).to eq(500)
1466
1466
  end
1467
1467
 
1468
- it "aliases the existance check" do
1468
+ it "aliases the existence check" do
1469
1469
  expect(product.cost?).to be true
1470
1470
  end
1471
1471
 
@@ -1506,7 +1506,7 @@ describe Mongoid::Attributes do
1506
1506
  expect(product.price).to eq(500)
1507
1507
  end
1508
1508
 
1509
- it "aliases the existance check" do
1509
+ it "aliases the existence check" do
1510
1510
  expect(product.price?).to be true
1511
1511
  end
1512
1512
 
@@ -8,6 +8,10 @@ describe Mongoid::Clients::Options do
8
8
 
9
9
  let(:options) { { database: 'test' } }
10
10
 
11
+ let!(:cluster) do
12
+ Band.mongo_client.cluster
13
+ end
14
+
11
15
  let!(:klass) do
12
16
  Band.with(options)
13
17
  end
@@ -33,6 +37,17 @@ describe Mongoid::Clients::Options do
33
37
  it "keeps the options" do
34
38
  expect(klass.persistence_options).to eq(options)
35
39
  end
40
+
41
+ context 'when changing the collection' do
42
+
43
+ let(:options) do
44
+ { collection: 'other' }
45
+ end
46
+
47
+ it 'uses that collection' do
48
+ expect(klass.collection.name).to eq(options[:collection])
49
+ end
50
+ end
36
51
  end
37
52
 
38
53
  context "when returning a criteria" do
@@ -413,7 +413,7 @@ describe Mongoid::Clients do
413
413
  context "when no client exists with the key" do
414
414
 
415
415
  before(:all) do
416
- Band.store_in(client: :nonexistant)
416
+ Band.store_in(client: :nonexistent)
417
417
  end
418
418
 
419
419
  let(:band) do
@@ -469,7 +469,7 @@ describe Mongoid::Clients do
469
469
  context "when no client exists with the key" do
470
470
 
471
471
  before(:all) do
472
- Band.store_in(client: :nonexistant)
472
+ Band.store_in(client: :nonexistent)
473
473
  end
474
474
 
475
475
  it "raises an error" do
@@ -749,6 +749,10 @@ describe Mongoid::Clients do
749
749
  expect(sess[:bands].find(name: "Tool")).to_not be_nil
750
750
  end
751
751
  end
752
+
753
+ it 'uses that database for the model mongo_client' do
754
+ expect(Band.mongo_client.database.name).to eq('mongoid_optional')
755
+ end
752
756
  end
753
757
  end
754
758
  end
@@ -197,7 +197,8 @@ describe Mongoid::Config do
197
197
  end
198
198
 
199
199
  it "sets the read option" do
200
- expect(options["read"]).to eq({ "mode" => :primary })
200
+ expect(options["read"]).to eq({ "mode" => :primary_preferred,
201
+ "tag_sets" => [{ "use" => "web" }]})
201
202
  end
202
203
  end
203
204
  end
@@ -218,7 +219,7 @@ describe Mongoid::Config do
218
219
  end
219
220
  end
220
221
 
221
- context "when provided a non-existant option" do
222
+ context "when provided a non-existent option" do
222
223
 
223
224
  it "raises an error" do
224
225
  expect {
@@ -145,7 +145,7 @@ describe Mongoid::Contextual::Aggregable::Mongo do
145
145
  context "when the field does not exist" do
146
146
 
147
147
  let(:aggregates) do
148
- context.aggregates(:non_existant)
148
+ context.aggregates(:non_existent)
149
149
  end
150
150
 
151
151
  it "returns an avg" do
@@ -234,7 +234,7 @@ describe Mongoid::Contextual::Aggregable::Mongo do
234
234
  end
235
235
 
236
236
  let(:aggregates) do
237
- context.aggregates(:non_existant)
237
+ context.aggregates(:non_existent)
238
238
  end
239
239
 
240
240
  it "returns nil" do
@@ -302,6 +302,29 @@ describe Mongoid::Contextual::Aggregable::Mongo do
302
302
 
303
303
  describe "#max" do
304
304
 
305
+ context 'when the field does not exist in any document' do
306
+
307
+ let!(:depeche) do
308
+ Band.create(name: "Depeche Mode", likes: 1000)
309
+ end
310
+
311
+ let(:criteria) do
312
+ Band.all
313
+ end
314
+
315
+ let(:context) do
316
+ Mongoid::Contextual::Mongo.new(criteria)
317
+ end
318
+
319
+ let(:max) do
320
+ context.max(:non_existent)
321
+ end
322
+
323
+ it 'returns nil' do
324
+ expect(max).to be(nil)
325
+ end
326
+ end
327
+
305
328
  context "when provided a single field" do
306
329
 
307
330
  let!(:depeche) do
@@ -254,7 +254,7 @@ describe Mongoid::Contextual::Atomic do
254
254
  expect(depeche_mode.reload.members).to eq([ "Dave" ])
255
255
  end
256
256
 
257
- it "does not error on non existant fields" do
257
+ it "does not error on non existent fields" do
258
258
  expect(smiths.reload.members).to be_nil
259
259
  end
260
260
  end
@@ -285,7 +285,7 @@ describe Mongoid::Contextual::Atomic do
285
285
  expect(depeche_mode.reload.members).to eq([ "Fletch" ])
286
286
  end
287
287
 
288
- it "does not error on non existant fields" do
288
+ it "does not error on non existent fields" do
289
289
  expect(smiths.reload.members).to be_nil
290
290
  end
291
291
  end
@@ -316,7 +316,7 @@ describe Mongoid::Contextual::Atomic do
316
316
  expect(depeche_mode.reload.members).to eq([ "Dave", "Alan" ])
317
317
  end
318
318
 
319
- it "pushes to non existant fields" do
319
+ it "pushes to non existent fields" do
320
320
  expect(smiths.reload.members).to eq([ "Alan" ])
321
321
  end
322
322
  end
@@ -347,7 +347,7 @@ describe Mongoid::Contextual::Atomic do
347
347
  expect(depeche_mode.reload.members).to eq([ "Dave", "Alan", "Fletch" ])
348
348
  end
349
349
 
350
- it "pushes to non existant fields" do
350
+ it "pushes to non existent fields" do
351
351
  expect(smiths.reload.members).to eq([ "Alan", "Fletch" ])
352
352
  end
353
353
  end
@@ -378,7 +378,7 @@ describe Mongoid::Contextual::Atomic do
378
378
  expect(depeche_mode.reload.artists).to eq([ "Dave" ])
379
379
  end
380
380
 
381
- it "does not rename non existant fields" do
381
+ it "does not rename non existent fields" do
382
382
  expect(smiths.reload).to_not respond_to(:artists)
383
383
  end
384
384
  end
@@ -409,7 +409,7 @@ describe Mongoid::Contextual::Atomic do
409
409
  expect(depeche_mode.reload.name).to eq("Recoil")
410
410
  end
411
411
 
412
- it "sets non existant fields" do
412
+ it "sets non existent fields" do
413
413
  expect(smiths.reload.name).to eq("Recoil")
414
414
  end
415
415
  end
@@ -757,7 +757,7 @@ describe Mongoid::Contextual::Mongo do
757
757
 
758
758
  context "when subsequently calling #last" do
759
759
 
760
- it "returns the correnct document" do
760
+ it "returns the correct document" do
761
761
  expect(context.send(method)).to eq(new_order)
762
762
  expect(context.last).to eq(depeche_mode)
763
763
  end
@@ -783,7 +783,7 @@ describe Mongoid::Contextual::Mongo do
783
783
 
784
784
  context "when subsequently calling #last" do
785
785
 
786
- it "returns the correnct document" do
786
+ it "returns the correct document" do
787
787
  expect(context.send(method)).to eq(new_order)
788
788
  expect(context.last).to eq(depeche_mode)
789
789
  end
@@ -854,79 +854,6 @@ describe Mongoid::Contextual::Mongo do
854
854
  end
855
855
  end
856
856
 
857
- pending "#last" do
858
-
859
- context "when no default scope" do
860
-
861
- let!(:depeche_mode) do
862
- Band.create(name: "Depeche Mode")
863
- end
864
-
865
- let!(:new_order) do
866
- Band.create(name: "New Order")
867
- end
868
-
869
- let(:criteria) do
870
- Band.all
871
- end
872
-
873
- let(:context) do
874
- described_class.new(criteria)
875
- end
876
-
877
- it "returns the last matching document" do
878
- expect(context.last).to eq(new_order)
879
- end
880
- end
881
-
882
- context "when default scope" do
883
-
884
- let!(:palm) do
885
- Tree.create(name: "Palm")
886
- end
887
-
888
- let!(:maple) do
889
- Tree.create(name: "Maple")
890
- end
891
-
892
- let(:criteria) do
893
- Tree.all
894
- end
895
-
896
- let(:context) do
897
- described_class.new(criteria)
898
- end
899
-
900
- it "respects default scope" do
901
- expect(context.last).to eq(palm)
902
- end
903
- end
904
-
905
- context "when subsequently calling #first" do
906
-
907
- let!(:depeche_mode) do
908
- Band.create(name: "Depeche Mode")
909
- end
910
-
911
- let!(:new_order) do
912
- Band.create(name: "New Order")
913
- end
914
-
915
- let(:criteria) do
916
- Band.asc(:name)
917
- end
918
-
919
- let(:context) do
920
- described_class.new(criteria)
921
- end
922
-
923
- it "returns the correnct document" do
924
- expect(context.last).to eq(new_order)
925
- expect(context.first).to eq(depeche_mode)
926
- end
927
- end
928
- end
929
-
930
857
  [ :length, :size ].each do |method|
931
858
 
932
859
  describe "##{method}" do
@@ -1805,4 +1732,30 @@ describe Mongoid::Contextual::Mongo do
1805
1732
  end
1806
1733
  end
1807
1734
  end
1735
+
1736
+ describe '#pipeline' do
1737
+
1738
+ context 'when the criteria has a selector' do
1739
+
1740
+ let(:criteria) do
1741
+ Band.where(name: "New Order")
1742
+ end
1743
+
1744
+ let(:context) do
1745
+ described_class.new(criteria)
1746
+ end
1747
+
1748
+ let(:matches_operators) do
1749
+ context.send(:pipeline, 'name').select { |o| o['$match'] }
1750
+ end
1751
+
1752
+ it 'creates a pipeline with the selector as one of the $match criteria' do
1753
+ expect(matches_operators).to include('$match' => criteria.selector)
1754
+ end
1755
+
1756
+ it 'creates a pipeline with the $exists operator as one of the $match criteria' do
1757
+ expect(matches_operators).to include('$match' => { 'name' => { '$exists' => true } })
1758
+ end
1759
+ end
1760
+ end
1808
1761
  end
@@ -2821,6 +2821,60 @@ describe Mongoid::Criteria do
2821
2821
  expect(criteria.first.likes).to eq(3)
2822
2822
  end
2823
2823
  end
2824
+
2825
+ context 'when the field is a subdocument' do
2826
+
2827
+ let(:criteria) do
2828
+ Band.where(name: 'FKA Twigs')
2829
+ end
2830
+
2831
+ context 'when a top-level field and a subdocument field are plucked' do
2832
+
2833
+ before do
2834
+ Band.create(name: 'FKA Twigs')
2835
+ Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
2836
+ end
2837
+
2838
+ let(:embedded_pluck) do
2839
+ criteria.pluck(:name, 'records.name')
2840
+ end
2841
+
2842
+ let(:expected) do
2843
+ [
2844
+ ["FKA Twigs", nil],
2845
+ ['FKA Twigs', [{ "name" => "LP1" }]]
2846
+ ]
2847
+ end
2848
+
2849
+ it 'returns the list of top-level field and subdocument values' do
2850
+ expect(embedded_pluck). to eq(expected)
2851
+ end
2852
+ end
2853
+
2854
+ context 'when only a subdocument field is plucked' do
2855
+
2856
+ before do
2857
+ Band.create(name: 'FKA Twigs')
2858
+ Band.create(name: 'FKA Twigs', records: [ Record.new(name: 'LP1') ])
2859
+ end
2860
+
2861
+ let(:embedded_pluck) do
2862
+ criteria.pluck('records.name')
2863
+ end
2864
+
2865
+ let(:expected) do
2866
+ [
2867
+ nil,
2868
+ [{ "name" => "LP1" }]
2869
+ ]
2870
+ end
2871
+
2872
+ it 'returns the list of subdocument values' do
2873
+ expect(embedded_pluck). to eq(expected)
2874
+ end
2875
+ end
2876
+
2877
+ end
2824
2878
  end
2825
2879
 
2826
2880
  context "when plucking mult-fields" do
@@ -123,7 +123,7 @@ describe Mongoid::Fields::Standard do
123
123
  end
124
124
  end
125
125
 
126
- context "when getting a non existant value" do
126
+ context "when getting a non existent value" do
127
127
 
128
128
  it "returns nil" do
129
129
  expect(hash[:key]).to be_nil
@@ -895,7 +895,7 @@ describe Mongoid::Fields do
895
895
  (person.testing = expect("Testy")).to eq("Testy")
896
896
  end
897
897
 
898
- it "adds an existance method" do
898
+ it "adds an existence method" do
899
899
  expect(Person.new.testing?).to be false
900
900
  end
901
901
 
@@ -96,7 +96,7 @@ describe Mongoid::Indexable::Specification do
96
96
  end
97
97
 
98
98
  it "normalizes the options" do
99
- expect(spec.options).to eq(background: true, dropDups: true)
99
+ expect(spec.options).to eq(background: true, drop_dups: true)
100
100
  end
101
101
  end
102
102
  end
@@ -192,8 +192,8 @@ describe Mongoid::Indexable do
192
192
  klass.index_specification(name: 1).options
193
193
  end
194
194
 
195
- it "sets the index with dropDups options" do
196
- expect(options).to eq(dropDups: true)
195
+ it "sets the index with drop_dups option" do
196
+ expect(options).to eq(drop_dups: true)
197
197
  end
198
198
  end
199
199
 
@@ -327,7 +327,7 @@ describe Mongoid::Indexable do
327
327
  end
328
328
  end
329
329
 
330
- context "when providing a geo haystack index" do
330
+ context "when providing a geo haystack index with a bucket_size" do
331
331
 
332
332
  before do
333
333
  klass.index({ location: "geoHaystack" }, { min: -200, max: 200, bucket_size: 0.5 })
@@ -337,8 +337,8 @@ describe Mongoid::Indexable do
337
337
  klass.index_specification(location: "geoHaystack").options
338
338
  end
339
339
 
340
- it "sets the geo haystack index" do
341
- expect(options).to eq({ min: -200, max: 200, bucketSize: 0.5 })
340
+ it "sets the geo haystack index with the bucket_size option" do
341
+ expect(options).to eq({ min: -200, max: 200, bucket_size: 0.5 })
342
342
  end
343
343
  end
344
344
 
@@ -490,8 +490,8 @@ describe Mongoid::Indexable do
490
490
  klass.index_specification(name: 1).options
491
491
  end
492
492
 
493
- it "sets the index with sparse options" do
494
- expect(options).to eq(expireAfterSeconds: 3600)
493
+ it "sets the index with expire_after option" do
494
+ expect(options).to eq(expire_after: 3600)
495
495
  end
496
496
  end
497
497