mongoid 5.0.0 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +2 -0
- data/CHANGELOG.md +54 -2
- data/lib/config/locales/en.yml +1 -1
- data/lib/mongoid/attributes.rb +1 -1
- data/lib/mongoid/clients.rb +7 -4
- data/lib/mongoid/clients/options.rb +2 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +2 -1
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +4 -1
- data/lib/mongoid/contextual/mongo.rb +4 -5
- data/lib/mongoid/document.rb +1 -0
- data/lib/mongoid/indexable/specification.rb +3 -5
- data/lib/mongoid/indexable/validators/options.rb +7 -1
- data/lib/mongoid/matchable/exists.rb +1 -1
- data/lib/mongoid/persistable.rb +2 -1
- data/lib/mongoid/persistable/creatable.rb +1 -1
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/positional.rb +75 -0
- data/lib/mongoid/relations/counter_cache.rb +19 -0
- data/lib/mongoid/relations/eager/base.rb +4 -2
- data/lib/mongoid/relations/embedded/batchable.rb +10 -3
- data/lib/mongoid/relations/proxy.rb +1 -1
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/scopable.rb +6 -5
- data/lib/mongoid/selectable.rb +36 -1
- data/lib/mongoid/threaded.rb +34 -2
- data/lib/mongoid/timestamps/created.rb +1 -2
- data/lib/mongoid/timestamps/timeless.rb +19 -2
- data/lib/mongoid/timestamps/updated.rb +1 -1
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +3 -1
- data/spec/app/models/account.rb +8 -0
- data/spec/app/models/answer.rb +2 -0
- data/spec/app/models/article.rb +2 -0
- data/spec/app/models/author.rb +2 -0
- data/spec/app/models/baby.rb +4 -0
- data/spec/app/models/book.rb +2 -0
- data/spec/app/models/consumption_period.rb +7 -0
- data/spec/app/models/exhibitor.rb +1 -0
- data/spec/app/models/kaleidoscope.rb +6 -0
- data/spec/app/models/kangaroo.rb +4 -0
- data/spec/app/models/note.rb +3 -0
- data/spec/app/models/page.rb +11 -0
- data/spec/app/models/simple.rb +5 -0
- data/spec/config/mongoid.yml +3 -1
- data/spec/mongoid/atomic/paths_spec.rb +17 -10
- data/spec/mongoid/attributes_spec.rb +2 -2
- data/spec/mongoid/clients/options_spec.rb +15 -0
- data/spec/mongoid/clients_spec.rb +6 -2
- data/spec/mongoid/config_spec.rb +3 -2
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +25 -2
- data/spec/mongoid/contextual/atomic_spec.rb +6 -6
- data/spec/mongoid/contextual/mongo_spec.rb +28 -75
- data/spec/mongoid/criteria_spec.rb +54 -0
- data/spec/mongoid/fields/standard_spec.rb +1 -1
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/indexable/specification_spec.rb +1 -1
- data/spec/mongoid/indexable_spec.rb +7 -7
- data/spec/mongoid/interceptable_spec.rb +55 -0
- data/spec/mongoid/persistable/creatable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +50 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +56 -4
- data/spec/mongoid/persistable/pushable_spec.rb +11 -0
- data/spec/mongoid/persistable/savable_spec.rb +20 -2
- data/spec/mongoid/positional_spec.rb +221 -0
- data/spec/mongoid/query_cache_spec.rb +19 -0
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +1 -1
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -11
- data/spec/mongoid/relations/eager/has_many_spec.rb +37 -0
- data/spec/mongoid/relations/eager_spec.rb +11 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +38 -9
- data/spec/mongoid/relations/embedded/one_spec.rb +1 -1
- data/spec/mongoid/relations/proxy_spec.rb +22 -0
- data/spec/mongoid/relations/reflections_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +160 -19
- data/spec/mongoid/selectable_spec.rb +16 -6
- data/spec/mongoid/timestamps/timeless_spec.rb +17 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +17 -0
- metadata +40 -5
- 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
|
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
|
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: :
|
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: :
|
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
|
data/spec/mongoid/config_spec.rb
CHANGED
@@ -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" => :
|
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-
|
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(:
|
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(:
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
data/spec/mongoid/fields_spec.rb
CHANGED
@@ -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
|
196
|
-
expect(options).to eq(
|
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,
|
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
|
494
|
-
expect(options).to eq(
|
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
|
|