mongoid 7.4.3 → 7.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/config/locales/en.yml +7 -0
  4. data/lib/mongoid/association/embedded/batchable.rb +3 -20
  5. data/lib/mongoid/association/macros.rb +20 -0
  6. data/lib/mongoid/association/referenced/has_many/enumerable.rb +12 -8
  7. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  8. data/lib/mongoid/atomic/paths/embedded/many.rb +0 -19
  9. data/lib/mongoid/config.rb +6 -1
  10. data/lib/mongoid/contextual/memory.rb +144 -12
  11. data/lib/mongoid/contextual/mongo.rb +118 -26
  12. data/lib/mongoid/contextual/none.rb +45 -1
  13. data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -0
  14. data/lib/mongoid/criteria/queryable/extensions/hash.rb +2 -0
  15. data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
  16. data/lib/mongoid/criteria/queryable/selectable.rb +26 -10
  17. data/lib/mongoid/criteria.rb +2 -0
  18. data/lib/mongoid/document.rb +2 -0
  19. data/lib/mongoid/equality.rb +4 -4
  20. data/lib/mongoid/errors/document_not_found.rb +23 -6
  21. data/lib/mongoid/fields.rb +145 -21
  22. data/lib/mongoid/findable.rb +20 -5
  23. data/lib/mongoid/version.rb +1 -1
  24. data/lib/mongoid/warnings.rb +29 -0
  25. data/lib/mongoid.rb +1 -0
  26. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
  27. data/spec/integration/i18n_fallbacks_spec.rb +15 -1
  28. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +0 -21
  29. data/spec/mongoid/association/embedded/embeds_many_models.rb +0 -121
  30. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +0 -8
  31. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +54 -0
  32. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +8 -24
  33. data/spec/mongoid/clients/options_spec.rb +1 -0
  34. data/spec/mongoid/config_spec.rb +10 -4
  35. data/spec/mongoid/contextual/memory_spec.rb +826 -65
  36. data/spec/mongoid/contextual/mongo_spec.rb +781 -18
  37. data/spec/mongoid/contextual/none_spec.rb +46 -0
  38. data/spec/mongoid/criteria/queryable/selectable_spec.rb +212 -39
  39. data/spec/mongoid/criteria_spec.rb +8 -0
  40. data/spec/mongoid/equality_spec.rb +12 -12
  41. data/spec/mongoid/errors/document_not_found_spec.rb +49 -0
  42. data/spec/mongoid/findable_spec.rb +30 -0
  43. data/spec/support/models/code.rb +2 -0
  44. data.tar.gz.sig +0 -0
  45. metadata +3 -2
  46. metadata.gz.sig +0 -0
@@ -63,12 +63,58 @@ describe Mongoid::Contextual::None do
63
63
  it "returns nil" do
64
64
  expect(context.first).to be_nil
65
65
  end
66
+
67
+ it "doen't raise when passing options" do
68
+ expect do
69
+ context.first(id_sort: :none)
70
+ end.to_not raise_error
71
+ end
72
+
73
+ it "returns nil when passing a hash" do
74
+ expect(context.first(id_sort: :none)).to be_nil
75
+ end
76
+
77
+ it "returns [] when passing a limit" do
78
+ expect(context.first(1)).to eq([])
79
+ end
66
80
  end
67
81
 
68
82
  describe "#last" do
69
83
  it "returns nil" do
70
84
  expect(context.last).to be_nil
71
85
  end
86
+
87
+ it "doen't raise when passing options" do
88
+ expect do
89
+ context.last(id_sort: :none)
90
+ end.to_not raise_error
91
+ end
92
+
93
+ it "returns nil when passing a hash" do
94
+ expect(context.last(id_sort: :none)).to be_nil
95
+ end
96
+
97
+ it "returns [] when passing a limit" do
98
+ expect(context.last(1)).to eq([])
99
+ end
100
+ end
101
+
102
+ describe "#take" do
103
+ it "returns nil" do
104
+ expect(context.take).to be_nil
105
+ end
106
+
107
+ it "returns nil with params" do
108
+ expect(context.take(1)).to eq([])
109
+ end
110
+ end
111
+
112
+ describe "#take!" do
113
+ it "raises an error" do
114
+ expect do
115
+ context.take!
116
+ end.to raise_error(Mongoid::Errors::DocumentNotFound, /Could not find a document of class Band./)
117
+ end
72
118
  end
73
119
 
74
120
  describe "#length" do
@@ -479,10 +479,24 @@ describe Mongoid::Criteria::Queryable::Selectable do
479
479
  query.elem_match(users: { name: "value" })
480
480
  end
481
481
 
482
- it "adds the $elemMatch expression" do
483
- expect(selection.selector).to eq({
484
- "users" => { "$elemMatch" => { name: "value" }}
485
- })
482
+ context "when overwrite_chained_operators is false" do
483
+ config_override :overwrite_chained_operators, false
484
+
485
+ it "adds the $elemMatch expression" do
486
+ expect(selection.selector).to eq({
487
+ "users" => { "$elemMatch" => { "name" => "value" }}
488
+ })
489
+ end
490
+ end
491
+
492
+ context "when overwrite_chained_operators is true" do
493
+ config_override :overwrite_chained_operators, true
494
+
495
+ it "adds the $elemMatch expression" do
496
+ expect(selection.selector).to eq({
497
+ "users" => { "$elemMatch" => { name: "value" }}
498
+ })
499
+ end
486
500
  end
487
501
 
488
502
  it "returns a cloned query" do
@@ -523,11 +537,26 @@ describe Mongoid::Criteria::Queryable::Selectable do
523
537
  )
524
538
  end
525
539
 
526
- it "adds the $elemMatch expression" do
527
- expect(selection.selector).to eq({
528
- "users" => { "$elemMatch" => { name: "value" }},
529
- "comments" => { "$elemMatch" => { text: "value" }}
530
- })
540
+ context "when overwrite_chained_operators is false" do
541
+ config_override :overwrite_chained_operators, false
542
+
543
+ it "adds the $elemMatch expression" do
544
+ expect(selection.selector).to eq({
545
+ "users" => { "$elemMatch" => { "name" => "value" }},
546
+ "comments" => { "$elemMatch" => { "text" => "value" }}
547
+ })
548
+ end
549
+ end
550
+
551
+ context "when overwrite_chained_operators is true" do
552
+ config_override :overwrite_chained_operators, true
553
+
554
+ it "adds the $elemMatch expression" do
555
+ expect(selection.selector).to eq({
556
+ "users" => { "$elemMatch" => { name: "value" }},
557
+ "comments" => { "$elemMatch" => { text: "value" }}
558
+ })
559
+ end
531
560
  end
532
561
 
533
562
  it "returns a cloned query" do
@@ -546,11 +575,26 @@ describe Mongoid::Criteria::Queryable::Selectable do
546
575
  elem_match(comments: { text: "value" })
547
576
  end
548
577
 
549
- it "adds the $elemMatch expression" do
550
- expect(selection.selector).to eq({
551
- "users" => { "$elemMatch" => { name: "value" }},
552
- "comments" => { "$elemMatch" => { text: "value" }}
553
- })
578
+ context "when overwrite_chained_operators is false" do
579
+ config_override :overwrite_chained_operators, false
580
+
581
+ it "adds the $elemMatch expression" do
582
+ expect(selection.selector).to eq({
583
+ "users" => { "$elemMatch" => { "name" => "value" }},
584
+ "comments" => { "$elemMatch" => { "text" => "value" }}
585
+ })
586
+ end
587
+ end
588
+
589
+ context "when overwrite_chained_operators is true" do
590
+ config_override :overwrite_chained_operators, true
591
+
592
+ it "adds the $elemMatch expression" do
593
+ expect(selection.selector).to eq({
594
+ "users" => { "$elemMatch" => { name: "value" }},
595
+ "comments" => { "$elemMatch" => { text: "value" }}
596
+ })
597
+ end
554
598
  end
555
599
 
556
600
  it "returns a cloned query" do
@@ -566,10 +610,25 @@ describe Mongoid::Criteria::Queryable::Selectable do
566
610
  elem_match(users: { state: "new" })
567
611
  end
568
612
 
569
- it "overrides the $elemMatch expression" do
570
- expect(selection.selector).to eq({
571
- "users" => { "$elemMatch" => { state: "new" }}
572
- })
613
+ context "when overwrite_chained_operators is false" do
614
+ config_override :overwrite_chained_operators, false
615
+
616
+ it "adds an $elemMatch expression" do
617
+ expect(selection.selector).to eq({
618
+ "users" => { "$elemMatch" => { "name" => "value" } },
619
+ "$and" => [ { "users" => { "$elemMatch" => { "state" => "new" } } } ],
620
+ })
621
+ end
622
+ end
623
+
624
+ context "when overwrite_chained_operators is true" do
625
+ config_override :overwrite_chained_operators, true
626
+
627
+ it "overrides the $elemMatch expression" do
628
+ expect(selection.selector).to eq({
629
+ "users" => { "$elemMatch" => { state: "new" }}
630
+ })
631
+ end
573
632
  end
574
633
 
575
634
  it "returns a cloned query" do
@@ -887,18 +946,40 @@ describe Mongoid::Criteria::Queryable::Selectable do
887
946
 
888
947
  context "when the criterion are on the same field" do
889
948
 
890
- let(:selection) do
891
- query.gt(first: 10).gt(first: 15)
892
- end
949
+ context "when overwrite_chained_operators is true" do
950
+ config_override :overwrite_chained_operators, true
893
951
 
894
- it "overwrites the first $gt selector" do
895
- expect(selection.selector).to eq({
896
- "first" => { "$gt" => 15 }
897
- })
952
+ let(:selection) do
953
+ query.gt(first: 10).gt(first: 15)
954
+ end
955
+
956
+ it "overwrites the first $gt selector" do
957
+ expect(selection.selector).to eq({
958
+ "first" => { "$gt" => 15 },
959
+ })
960
+ end
961
+
962
+ it "returns a cloned query" do
963
+ expect(selection).to_not equal(query)
964
+ end
898
965
  end
899
966
 
900
- it "returns a cloned query" do
901
- expect(selection).to_not equal(query)
967
+ context "when overwrite_chained_operators is false" do
968
+ config_override :overwrite_chained_operators, false
969
+ let(:selection) do
970
+ query.gt(first: 10).gt(first: 15)
971
+ end
972
+
973
+ it "overwrites the first $gt selector" do
974
+ expect(selection.selector).to eq({
975
+ "first" => { "$gt" => 10 },
976
+ "$and" => [{ "first" => { "$gt" => 15 } }]
977
+ })
978
+ end
979
+
980
+ it "returns a cloned query" do
981
+ expect(selection).to_not equal(query)
982
+ end
902
983
  end
903
984
  end
904
985
  end
@@ -975,10 +1056,25 @@ describe Mongoid::Criteria::Queryable::Selectable do
975
1056
  query.gte(first: 10).gte(first: 15)
976
1057
  end
977
1058
 
978
- it "overwrites the first $gte selector" do
979
- expect(selection.selector).to eq({
980
- "first" => { "$gte" => 15 }
981
- })
1059
+ context "when overwrite_chained_operators is false" do
1060
+ config_override :overwrite_chained_operators, false
1061
+
1062
+ it "adds a second $gte selector" do
1063
+ expect(selection.selector).to eq({
1064
+ "first" => { "$gte" => 10 },
1065
+ "$and" => [ { "first" => { "$gte" => 15 } } ]
1066
+ })
1067
+ end
1068
+ end
1069
+
1070
+ context "when overwrite_chained_operators is true" do
1071
+ config_override :overwrite_chained_operators, true
1072
+
1073
+ it "overwrites the first $gte selector" do
1074
+ expect(selection.selector).to eq({
1075
+ "first" => { "$gte" => 15 }
1076
+ })
1077
+ end
982
1078
  end
983
1079
 
984
1080
  it "returns a cloned query" do
@@ -1152,10 +1248,25 @@ describe Mongoid::Criteria::Queryable::Selectable do
1152
1248
  query.lt(first: 10).lt(first: 15)
1153
1249
  end
1154
1250
 
1155
- it "overwrites the first $lt selector" do
1156
- expect(selection.selector).to eq({
1157
- "first" => { "$lt" => 15 }
1158
- })
1251
+ context "when overwrite_chained_operators is false" do
1252
+ config_override :overwrite_chained_operators, false
1253
+
1254
+ it "adds a second $lt selector" do
1255
+ expect(selection.selector).to eq({
1256
+ "first" => { "$lt" => 10 },
1257
+ "$and" => [ { "first" => { "$lt" => 15 } } ]
1258
+ })
1259
+ end
1260
+ end
1261
+
1262
+ context "when overwrite_chained_operators is true" do
1263
+ config_override :overwrite_chained_operators, true
1264
+
1265
+ it "overwrites the first $lt selector" do
1266
+ expect(selection.selector).to eq({
1267
+ "first" => { "$lt" => 15 }
1268
+ })
1269
+ end
1159
1270
  end
1160
1271
 
1161
1272
  it "returns a cloned query" do
@@ -1236,10 +1347,25 @@ describe Mongoid::Criteria::Queryable::Selectable do
1236
1347
  query.lte(first: 10).lte(first: 15)
1237
1348
  end
1238
1349
 
1239
- it "overwrites the first $lte selector" do
1240
- expect(selection.selector).to eq({
1241
- "first" => { "$lte" => 15 }
1242
- })
1350
+ context "when overwrite_chained_operators is false" do
1351
+ config_override :overwrite_chained_operators, false
1352
+
1353
+ it "adds a second $lte selector" do
1354
+ expect(selection.selector).to eq({
1355
+ "first" => { "$lte" => 10 },
1356
+ "$and" => [ { "first" => { "$lte" => 15 } } ]
1357
+ })
1358
+ end
1359
+ end
1360
+
1361
+ context "when overwrite_chained_operators is true" do
1362
+ config_override :overwrite_chained_operators, true
1363
+
1364
+ it "overwrites the first $lte selector" do
1365
+ expect(selection.selector).to eq({
1366
+ "first" => { "$lte" => 15 }
1367
+ })
1368
+ end
1243
1369
  end
1244
1370
 
1245
1371
  it "returns a cloned query" do
@@ -2294,4 +2420,51 @@ describe Mongoid::Criteria::Queryable::Selectable do
2294
2420
  end
2295
2421
  end
2296
2422
  end
2423
+
2424
+ describe "Mongoid.overwrite_chained_operators" do
2425
+ [ :eq, :elem_match, :gt, :gte, :lt, :lte, :mod, :ne, :near, :near_sphere ].each do |meth|
2426
+
2427
+ context "when chaining the #{meth} method when using the same field" do
2428
+ let(:op) do
2429
+ {
2430
+ eq: "$eq",
2431
+ elem_match: "$elemMatch",
2432
+ gt: "$gt",
2433
+ gte: "$gte",
2434
+ lt: "$lt",
2435
+ lte: "$lte",
2436
+ mod: "$mod",
2437
+ ne: "$ne",
2438
+ near: "$near",
2439
+ near_sphere: "$nearSphere"
2440
+ }[meth]
2441
+ end
2442
+
2443
+ let(:criteria) do
2444
+ Band.send(meth, {views: 1}).send(meth, {views:2})
2445
+ end
2446
+
2447
+ context "when overwrite_chained_operators is true" do
2448
+ config_override :overwrite_chained_operators, true
2449
+
2450
+ it "overrides the previous operators" do
2451
+ expect(criteria.selector).to eq({
2452
+ "views" => { op => 2 },
2453
+ })
2454
+ end
2455
+ end
2456
+
2457
+ context "when overwrite_chained_operators is false" do
2458
+ config_override :overwrite_chained_operators, false
2459
+
2460
+ it "overrides the previous operators" do
2461
+ expect(criteria.selector).to eq({
2462
+ "views" => { op => 1 },
2463
+ "$and" => [{ "views" => { op => 2 } }]
2464
+ })
2465
+ end
2466
+ end
2467
+ end
2468
+ end
2469
+ end
2297
2470
  end
@@ -3183,6 +3183,10 @@ describe Mongoid::Criteria do
3183
3183
  I18n.fallbacks = prev_fallbacks
3184
3184
  end
3185
3185
 
3186
+ after do
3187
+ I18n.locale = :en
3188
+ end
3189
+
3186
3190
  let(:plucked) do
3187
3191
  Dictionary.all.pluck(:description).first
3188
3192
  end
@@ -3218,6 +3222,10 @@ describe Mongoid::Criteria do
3218
3222
  Person.create!(passport: p, employer_id: 12345)
3219
3223
  end
3220
3224
 
3225
+ after do
3226
+ I18n.locale = :en
3227
+ end
3228
+
3221
3229
  let(:plucked) do
3222
3230
  Person.where(employer_id: 12345).pluck("pass.name").first
3223
3231
  end
@@ -85,8 +85,8 @@ describe Mongoid::Equality do
85
85
 
86
86
  describe ".===" do
87
87
 
88
- context "when legacy_triple_equals is not set" do
89
- config_override :legacy_triple_equals, false
88
+ context "when legacy_triple_equals is set" do
89
+ config_override :legacy_triple_equals, true
90
90
 
91
91
  context "when comparable is an instance of this document" do
92
92
 
@@ -128,8 +128,8 @@ describe Mongoid::Equality do
128
128
  end
129
129
  end
130
130
 
131
- context "when legacy_triple_equals is set" do
132
- config_override :legacy_triple_equals, true
131
+ context "when legacy_triple_equals is not set" do
132
+ config_override :legacy_triple_equals, false
133
133
 
134
134
  context "when comparable is an instance of this document" do
135
135
 
@@ -205,8 +205,8 @@ describe Mongoid::Equality do
205
205
 
206
206
  context "when the class is the same" do
207
207
 
208
- it "returns true" do
209
- expect(person === Person).to be true
208
+ it "returns false" do
209
+ expect(person === Person).to be false
210
210
  end
211
211
  end
212
212
 
@@ -219,8 +219,8 @@ describe Mongoid::Equality do
219
219
 
220
220
  context "when the class is a superclass" do
221
221
 
222
- it "returns true" do
223
- expect(Doctor.new === Person).to be true
222
+ it "returns false" do
223
+ expect(Doctor.new === Person).to be false
224
224
  end
225
225
  end
226
226
  end
@@ -256,8 +256,8 @@ describe Mongoid::Equality do
256
256
  context "when comparing to a class" do
257
257
  context "when the class is the same" do
258
258
 
259
- it "returns false" do
260
- expect(person === Person).to be false
259
+ it "returns true" do
260
+ expect(person === Person).to be true
261
261
  end
262
262
  end
263
263
 
@@ -270,8 +270,8 @@ describe Mongoid::Equality do
270
270
 
271
271
  context "when the class is a superclass" do
272
272
 
273
- it "returns false" do
274
- expect(Doctor.new === Person).to be false
273
+ it "returns true" do
274
+ expect(Doctor.new === Person).to be true
275
275
  end
276
276
  end
277
277
  end
@@ -80,6 +80,55 @@ describe Mongoid::Errors::DocumentNotFound do
80
80
  )
81
81
  end
82
82
  end
83
+
84
+ context "when providing an id in a hash without a shard key" do
85
+
86
+ let(:error) do
87
+ described_class.new(Person, 1, 1)
88
+ end
89
+
90
+ it "contains the problem in the message" do
91
+ expect(error.message).to include(
92
+ "Document(s) not found for class Person with id(s) 1."
93
+ )
94
+ end
95
+
96
+ it "contains the summary in the message" do
97
+ expect(error.message).to include(
98
+ "When calling Person.find with an id or array of ids"
99
+ )
100
+ end
101
+
102
+ it "contains the resolution in the message" do
103
+ expect(error.message).to include(
104
+ "Search for an id that is in the database or set the"
105
+ )
106
+ end
107
+ end
108
+
109
+ context "when not providing params or unmatched" do
110
+ let(:error) do
111
+ described_class.new(Person, nil, nil)
112
+ end
113
+
114
+ it "contains the problem in the message" do
115
+ expect(error.message).to include(
116
+ "Could not find a document of class Person."
117
+ )
118
+ end
119
+
120
+ it "contains the summary in the message" do
121
+ expect(error.message).to include(
122
+ "Mongoid attempted to find a document of the class Person but none exist."
123
+ )
124
+ end
125
+
126
+ it "contains the resolution in the message" do
127
+ expect(error.message).to include(
128
+ "Create a document of class Person or use a finder method that returns nil when no documents are found instead of raising an exception."
129
+ )
130
+ end
131
+ end
83
132
  end
84
133
 
85
134
  describe "#params" do
@@ -229,6 +229,36 @@ describe Mongoid::Findable do
229
229
  it "returns the first matching document" do
230
230
  expect(Person.send(method)).to eq(person)
231
231
  end
232
+
233
+ it "doen't raise when passing options" do
234
+ expect do
235
+ Person.first(id_sort: :none)
236
+ end.to_not raise_error
237
+ end
238
+
239
+ it "passes the limit through" do
240
+ Person.first(1).length.should == 1
241
+ end
242
+ end
243
+ end
244
+
245
+ describe "#last" do
246
+ let!(:person) do
247
+ Person.create!
248
+ end
249
+
250
+ it "returns the first matching document" do
251
+ expect(Person.last).to eq(person)
252
+ end
253
+
254
+ it "doen't raise when passing options" do
255
+ expect do
256
+ Person.last(id_sort: :none)
257
+ end.to_not raise_error
258
+ end
259
+
260
+ it "passes the limit through" do
261
+ Person.last(1).length.should == 1
232
262
  end
233
263
  end
234
264
 
@@ -10,4 +10,6 @@ end
10
10
  class Deepest
11
11
  include Mongoid::Document
12
12
  embedded_in :code
13
+
14
+ field :array, type: Array
13
15
  end
data.tar.gz.sig CHANGED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongoid
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.4.3
4
+ version: 7.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Durran Jordan
@@ -30,7 +30,7 @@ cert_chain:
30
30
  +WyKQ+QTIdtDiyf2LQmxWnxt/W1CmScjdLS7/yXGkkB/D9Uy+sJD747O/B9P238Q
31
31
  XnerrtyOu04RsWDvaZkCwSDVzoqfICh4CP1mlde73Ts=
32
32
  -----END CERTIFICATE-----
33
- date: 2022-07-23 00:00:00.000000000 Z
33
+ date: 2022-07-20 00:00:00.000000000 Z
34
34
  dependencies:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: activemodel
@@ -452,6 +452,7 @@ files:
452
452
  - lib/mongoid/validatable/queryable.rb
453
453
  - lib/mongoid/validatable/uniqueness.rb
454
454
  - lib/mongoid/version.rb
455
+ - lib/mongoid/warnings.rb
455
456
  - lib/rails/generators/mongoid/config/config_generator.rb
456
457
  - lib/rails/generators/mongoid/config/templates/mongoid.yml
457
458
  - lib/rails/generators/mongoid/model/model_generator.rb
metadata.gz.sig CHANGED
Binary file