mongoid 8.0.3 → 8.0.5

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 (38) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Rakefile +25 -0
  4. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +17 -15
  5. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +4 -0
  6. data/lib/mongoid/association/referenced/has_many/proxy.rb +4 -0
  7. data/lib/mongoid/atomic.rb +7 -0
  8. data/lib/mongoid/changeable.rb +1 -3
  9. data/lib/mongoid/criteria/queryable/extensions/array.rb +1 -1
  10. data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -1
  11. data/lib/mongoid/criteria/queryable/extensions/numeric.rb +0 -8
  12. data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -11
  13. data/lib/mongoid/criteria/queryable/extensions/symbol.rb +0 -10
  14. data/lib/mongoid/criteria/translator.rb +45 -0
  15. data/lib/mongoid/criteria.rb +1 -0
  16. data/lib/mongoid/document.rb +50 -13
  17. data/lib/mongoid/factory.rb +21 -8
  18. data/lib/mongoid/matcher.rb +21 -6
  19. data/lib/mongoid/reloadable.rb +3 -5
  20. data/lib/mongoid/shardable.rb +35 -11
  21. data/lib/mongoid/threaded.rb +30 -0
  22. data/lib/mongoid/traversable.rb +1 -1
  23. data/lib/mongoid/version.rb +1 -1
  24. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +37 -32
  25. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +143 -197
  26. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +102 -114
  27. data/spec/mongoid/attributes_spec.rb +2 -2
  28. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
  29. data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
  30. data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -0
  31. data/spec/mongoid/criteria/translator_spec.rb +132 -0
  32. data/spec/mongoid/reloadable_spec.rb +24 -0
  33. data/spec/mongoid/shardable_models.rb +14 -0
  34. data/spec/mongoid/shardable_spec.rb +153 -61
  35. data/spec/mongoid_spec.rb +1 -1
  36. data.tar.gz.sig +0 -0
  37. metadata +656 -648
  38. metadata.gz.sig +0 -0
@@ -2,6 +2,26 @@
2
2
 
3
3
  require "spec_helper"
4
4
 
5
+ module RefHasManySpec
6
+ module OverrideInitialize
7
+ class Parent
8
+ include Mongoid::Document
9
+ has_many :children, inverse_of: :parent
10
+ end
11
+
12
+ class Child
13
+ include Mongoid::Document
14
+ belongs_to :parent
15
+ field :name, type: String
16
+
17
+ def initialize(*args)
18
+ super
19
+ self.name ||= "default"
20
+ end
21
+ end
22
+ end
23
+ end
24
+
5
25
  describe Mongoid::Association::Referenced::HasMany::Proxy do
6
26
 
7
27
  before :all do
@@ -877,6 +897,14 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
877
897
  [ :build, :new ].each do |method|
878
898
 
879
899
  describe "##{method}" do
900
+ context 'when model has #initialize' do
901
+ let(:parent) { RefHasManySpec::OverrideInitialize::Parent.create }
902
+ let(:child) { parent.children.send(method) }
903
+
904
+ it 'should call #initialize' do
905
+ expect(child.name).to be == "default"
906
+ end
907
+ end
880
908
 
881
909
  context "when the association is not polymorphic" do
882
910
 
@@ -2077,154 +2105,114 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
2077
2105
  end
2078
2106
  end
2079
2107
 
2080
- describe "#delete" do
2081
-
2082
- let!(:person) do
2083
- Person.create!(username: 'arthurnn')
2084
- end
2108
+ %i[ delete delete_one ].each do |method|
2109
+ describe "##{method}" do
2110
+ let!(:person) { Person.create!(username: 'arthurnn') }
2085
2111
 
2086
- context "when the document is found" do
2112
+ context 'when the document is found' do
2113
+ context 'when no dependent option is set' do
2114
+ context 'when we are assigning attributes' do
2115
+ let!(:drug) { person.drugs.create! }
2116
+ let(:deleted) { person.drugs.send(method, drug) }
2087
2117
 
2088
- context "when no dependent option is set" do
2118
+ before do
2119
+ Mongoid::Threaded.begin_execution(:assign)
2120
+ end
2089
2121
 
2090
- context "when we are assigning attributes" do
2122
+ after do
2123
+ Mongoid::Threaded.exit_execution(:assign)
2124
+ end
2091
2125
 
2092
- let!(:drug) do
2093
- person.drugs.create!
2126
+ it 'does not cascade' do
2127
+ expect(deleted.changes.keys).to eq([ 'person_id' ])
2128
+ end
2094
2129
  end
2095
2130
 
2096
- before do
2097
- Mongoid::Threaded.begin_execution(:assign)
2098
- end
2131
+ context 'when the document is loaded' do
2132
+ let!(:drug) { person.drugs.create! }
2133
+ let!(:deleted) { person.drugs.send(method, drug) }
2099
2134
 
2100
- after do
2101
- Mongoid::Threaded.exit_execution(:assign)
2102
- end
2135
+ it 'returns the document' do
2136
+ expect(deleted).to eq(drug)
2137
+ end
2103
2138
 
2104
- let(:deleted) do
2105
- person.drugs.delete(drug)
2106
- end
2139
+ it 'deletes the foreign key' do
2140
+ expect(drug.person_id).to be_nil
2141
+ end
2107
2142
 
2108
- it "does not cascade" do
2109
- expect(deleted.changes.keys).to eq([ "person_id" ])
2143
+ it 'removes the document from the association' do
2144
+ expect(person.drugs).not_to include(drug)
2145
+ end
2110
2146
  end
2111
- end
2112
2147
 
2113
- context "when the document is loaded" do
2148
+ context 'when the document is not loaded' do
2149
+ let!(:drug) { Drug.create!(person_id: person.username) }
2150
+ let!(:deleted) { person.drugs.send(method, drug) }
2114
2151
 
2115
- let!(:drug) do
2116
- person.drugs.create!
2117
- end
2152
+ it 'returns the document' do
2153
+ expect(deleted).to eq(drug)
2154
+ end
2118
2155
 
2119
- let!(:deleted) do
2120
- person.drugs.delete(drug)
2121
- end
2156
+ it 'deletes the foreign key' do
2157
+ expect(drug.person_id).to be_nil
2158
+ end
2122
2159
 
2123
- it "returns the document" do
2124
- expect(deleted).to eq(drug)
2160
+ it 'removes the document from the association' do
2161
+ expect(person.drugs).not_to include(drug)
2162
+ end
2125
2163
  end
2164
+ end
2126
2165
 
2127
- it "deletes the foreign key" do
2128
- expect(drug.person_id).to be_nil
2129
- end
2166
+ context 'when dependent is delete' do
2167
+ context 'when the document is loaded' do
2168
+ let!(:post) { person.posts.create!(title: 'test') }
2169
+ let!(:deleted) { person.posts.send(method, post) }
2130
2170
 
2131
- it "removes the document from the association" do
2132
- expect(person.drugs).to_not include(drug)
2133
- end
2134
- end
2171
+ it 'returns the document' do
2172
+ expect(deleted).to eq(post)
2173
+ end
2135
2174
 
2136
- context "when the document is not loaded" do
2175
+ it 'deletes the document' do
2176
+ expect(post).to be_destroyed
2177
+ end
2137
2178
 
2138
- let!(:drug) do
2139
- Drug.create!(person_id: person.username)
2179
+ it 'removes the document from the association' do
2180
+ expect(person.posts).not_to include(post)
2181
+ end
2140
2182
  end
2141
2183
 
2142
- let!(:deleted) do
2143
- person.drugs.delete(drug)
2144
- end
2184
+ context 'when the document is not loaded' do
2185
+ let!(:post) { Post.create!(title: 'foo', person_id: person.id) }
2186
+ let!(:deleted) { person.posts.send(method, post) }
2145
2187
 
2146
- it "returns the document" do
2147
- expect(deleted).to eq(drug)
2148
- end
2188
+ it 'returns the document' do
2189
+ expect(deleted).to eq(post)
2190
+ end
2149
2191
 
2150
- it "deletes the foreign key" do
2151
- expect(drug.person_id).to be_nil
2152
- end
2192
+ it 'deletes the document' do
2193
+ expect(post).to be_destroyed
2194
+ end
2153
2195
 
2154
- it "removes the document from the association" do
2155
- expect(person.drugs).to_not include(drug)
2196
+ it 'removes the document from the association' do
2197
+ expect(person.posts).not_to include(post)
2198
+ end
2156
2199
  end
2157
2200
  end
2158
2201
  end
2159
2202
 
2160
- context "when dependent is delete" do
2203
+ context 'when the document is not found' do
2204
+ let!(:post) { Post.create!(title: 'foo') }
2205
+ let!(:deleted) { person.posts.send(method, post) }
2161
2206
 
2162
- context "when the document is loaded" do
2163
-
2164
- let!(:post) do
2165
- person.posts.create!(title: "test")
2166
- end
2167
-
2168
- let!(:deleted) do
2169
- person.posts.delete(post)
2170
- end
2171
-
2172
- it "returns the document" do
2173
- expect(deleted).to eq(post)
2174
- end
2175
-
2176
- it "deletes the document" do
2177
- expect(post).to be_destroyed
2178
- end
2179
-
2180
- it "removes the document from the association" do
2181
- expect(person.posts).to_not include(post)
2182
- end
2207
+ it 'returns nil' do
2208
+ expect(deleted).to be_nil
2183
2209
  end
2184
2210
 
2185
- context "when the document is not loaded" do
2186
-
2187
- let!(:post) do
2188
- Post.create!(title: "foo", person_id: person.id)
2189
- end
2190
-
2191
- let!(:deleted) do
2192
- person.posts.delete(post)
2193
- end
2194
-
2195
- it "returns the document" do
2196
- expect(deleted).to eq(post)
2197
- end
2198
-
2199
- it "deletes the document" do
2200
- expect(post).to be_destroyed
2201
- end
2202
-
2203
- it "removes the document from the association" do
2204
- expect(person.posts).to_not include(post)
2205
- end
2211
+ it 'does not delete the document' do
2212
+ expect(post).to be_persisted
2206
2213
  end
2207
2214
  end
2208
2215
  end
2209
-
2210
- context "when the document is not found" do
2211
-
2212
- let!(:post) do
2213
- Post.create!(title: "foo")
2214
- end
2215
-
2216
- let!(:deleted) do
2217
- person.posts.delete(post)
2218
- end
2219
-
2220
- it "returns nil" do
2221
- expect(deleted).to be_nil
2222
- end
2223
-
2224
- it "does not delete the document" do
2225
- expect(post).to be_persisted
2226
- end
2227
- end
2228
2216
  end
2229
2217
 
2230
2218
  [ :delete_all, :destroy_all ].each do |method|
@@ -2499,7 +2499,7 @@ describe Mongoid::Attributes do
2499
2499
  end
2500
2500
  end
2501
2501
 
2502
- context "when doing delete_one" do
2502
+ context "when doing _remove" do
2503
2503
  let(:doc) { NestedBook.create! }
2504
2504
  let(:page) { NestedPage.new }
2505
2505
  before do
@@ -2507,7 +2507,7 @@ describe Mongoid::Attributes do
2507
2507
  doc.pages << NestedPage.new
2508
2508
  doc.pages << NestedPage.new
2509
2509
 
2510
- doc.pages.send(:delete_one, page)
2510
+ doc.pages._remove(page)
2511
2511
  end
2512
2512
 
2513
2513
  it "updates the attributes" do
@@ -253,65 +253,6 @@ describe String do
253
253
  end
254
254
  end
255
255
 
256
- describe "#to_direction" do
257
-
258
- context "when ascending" do
259
-
260
- it "returns 1" do
261
- expect("ascending".to_direction).to eq(1)
262
- end
263
- end
264
-
265
- context "when asc" do
266
-
267
- it "returns 1" do
268
- expect("asc".to_direction).to eq(1)
269
- end
270
- end
271
-
272
- context "when ASCENDING" do
273
-
274
- it "returns 1" do
275
- expect("ASCENDING".to_direction).to eq(1)
276
- end
277
- end
278
-
279
- context "when ASC" do
280
-
281
- it "returns 1" do
282
- expect("ASC".to_direction).to eq(1)
283
- end
284
- end
285
-
286
- context "when descending" do
287
-
288
- it "returns -1" do
289
- expect("descending".to_direction).to eq(-1)
290
- end
291
- end
292
-
293
- context "when desc" do
294
-
295
- it "returns -1" do
296
- expect("desc".to_direction).to eq(-1)
297
- end
298
- end
299
-
300
- context "when DESCENDING" do
301
-
302
- it "returns -1" do
303
- expect("DESCENDING".to_direction).to eq(-1)
304
- end
305
- end
306
-
307
- context "when DESC" do
308
-
309
- it "returns -1" do
310
- expect("DESC".to_direction).to eq(-1)
311
- end
312
- end
313
- end
314
-
315
256
  describe ".evolve" do
316
257
 
317
258
  context "when provided a regex" do
@@ -107,63 +107,4 @@ describe Symbol do
107
107
  end
108
108
  end
109
109
  end
110
-
111
- describe "#to_direction" do
112
-
113
- context "when ascending" do
114
-
115
- it "returns 1" do
116
- expect(:ascending.to_direction).to eq(1)
117
- end
118
- end
119
-
120
- context "when asc" do
121
-
122
- it "returns 1" do
123
- expect(:asc.to_direction).to eq(1)
124
- end
125
- end
126
-
127
- context "when ASCENDING" do
128
-
129
- it "returns 1" do
130
- expect(:ASCENDING.to_direction).to eq(1)
131
- end
132
- end
133
-
134
- context "when ASC" do
135
-
136
- it "returns 1" do
137
- expect(:ASC.to_direction).to eq(1)
138
- end
139
- end
140
-
141
- context "when descending" do
142
-
143
- it "returns -1" do
144
- expect(:descending.to_direction).to eq(-1)
145
- end
146
- end
147
-
148
- context "when desc" do
149
-
150
- it "returns -1" do
151
- expect(:desc.to_direction).to eq(-1)
152
- end
153
- end
154
-
155
- context "when DESCENDING" do
156
-
157
- it "returns -1" do
158
- expect(:DESCENDING.to_direction).to eq(-1)
159
- end
160
- end
161
-
162
- context "when DESC" do
163
-
164
- it "returns -1" do
165
- expect(:DESC.to_direction).to eq(-1)
166
- end
167
- end
168
- end
169
110
  end
@@ -741,6 +741,21 @@ describe Mongoid::Criteria::Queryable::Optional do
741
741
 
742
742
  it_behaves_like "a cloning option"
743
743
  end
744
+
745
+ context "when the hash has hash values" do
746
+
747
+ let(:selection) do
748
+ query.send("#{method}", score: { "$meta" => "textScore"})
749
+ end
750
+
751
+ it "adds the sorting criteria" do
752
+ expect(selection.options).to eq(
753
+ { sort: { "score" => { "$meta" => "textScore" } }}
754
+ )
755
+ end
756
+
757
+ it_behaves_like "a cloning option"
758
+ end
744
759
  end
745
760
 
746
761
  context "when provided an array" do
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Mongoid::Criteria::Translator do
6
+ describe "#to_direction" do
7
+ context "when the value is a string" do
8
+ context "when ascending" do
9
+ it "returns 1" do
10
+ expect(described_class.to_direction("ascending")).to eq(1)
11
+ end
12
+ end
13
+
14
+ context "when asc" do
15
+ it "returns 1" do
16
+ expect(described_class.to_direction("asc")).to eq(1)
17
+ end
18
+ end
19
+
20
+ context "when ASCENDING" do
21
+ it "returns 1" do
22
+ expect(described_class.to_direction("ASCENDING")).to eq(1)
23
+ end
24
+ end
25
+
26
+ context "when ASC" do
27
+ it "returns 1" do
28
+ expect(described_class.to_direction("ASC")).to eq(1)
29
+ end
30
+ end
31
+
32
+ context "when descending" do
33
+ it "returns -1" do
34
+ expect(described_class.to_direction("descending")).to eq(-1)
35
+ end
36
+ end
37
+
38
+ context "when desc" do
39
+ it "returns -1" do
40
+ expect(described_class.to_direction("desc")).to eq(-1)
41
+ end
42
+ end
43
+
44
+ context "when DESCENDING" do
45
+ it "returns -1" do
46
+ expect(described_class.to_direction("DESCENDING")).to eq(-1)
47
+ end
48
+ end
49
+
50
+ context "when DESC" do
51
+ it "returns -1" do
52
+ expect(described_class.to_direction("DESC")).to eq(-1)
53
+ end
54
+ end
55
+ end
56
+
57
+ context "when the value is a symbol" do
58
+ context "when ascending" do
59
+ it "returns 1" do
60
+ expect(described_class.to_direction(:ascending)).to eq(1)
61
+ end
62
+ end
63
+
64
+ context "when asc" do
65
+ it "returns 1" do
66
+ expect(described_class.to_direction(:asc)).to eq(1)
67
+ end
68
+ end
69
+
70
+ context "when ASCENDING" do
71
+ it "returns 1" do
72
+ expect(described_class.to_direction(:ASCENDING)).to eq(1)
73
+ end
74
+ end
75
+
76
+ context "when ASC" do
77
+ it "returns 1" do
78
+ expect(described_class.to_direction(:ASC)).to eq(1)
79
+ end
80
+ end
81
+
82
+ context "when descending" do
83
+ it "returns -1" do
84
+ expect(described_class.to_direction(:descending)).to eq(-1)
85
+ end
86
+ end
87
+
88
+ context "when desc" do
89
+ it "returns -1" do
90
+ expect(described_class.to_direction(:desc)).to eq(-1)
91
+ end
92
+ end
93
+
94
+ context "when DESCENDING" do
95
+ it "returns -1" do
96
+ expect(described_class.to_direction(:DESCENDING)).to eq(-1)
97
+ end
98
+ end
99
+
100
+ context "when DESC" do
101
+ it "returns -1" do
102
+ expect(described_class.to_direction(:DESC)).to eq(-1)
103
+ end
104
+ end
105
+ end
106
+
107
+ context "when the value is numeric" do
108
+ it "should pass the value through unchanged" do
109
+ expect(described_class.to_direction(1)).to eq(1)
110
+ expect(described_class.to_direction(-1)).to eq(-1)
111
+ expect(described_class.to_direction(Math::PI)).to eq(Math::PI)
112
+ end
113
+ end
114
+
115
+ context "when the value is a hash" do
116
+ it "should pass the value through unchanged" do
117
+ expect(described_class.to_direction({})).to eq({})
118
+ expect(described_class.to_direction(scope: { "$meta" => "textScore" }))
119
+ .to eq(scope: { "$meta" => "textScore" })
120
+ expect(described_class.to_direction(a: 1, b: 2)).to eq(a: 1, b: 2)
121
+ end
122
+ end
123
+
124
+ context "when the value is an unrecognized type" do
125
+ it "should raise ArgumentError" do
126
+ expect { described_class.to_direction([]) }.to raise_error(ArgumentError)
127
+ expect { described_class.to_direction(/a/) }.to raise_error(ArgumentError)
128
+ expect { described_class.to_direction(Object.new) }.to raise_error(ArgumentError)
129
+ end
130
+ end
131
+ end
132
+ end
@@ -390,6 +390,30 @@ describe Mongoid::Reloadable do
390
390
  end
391
391
  end
392
392
 
393
+ context 'when embeds_many is modified' do
394
+ let(:contractor1) { Contractor.new(name: 'b') }
395
+ let(:contractor2) { Contractor.new(name: 'c') }
396
+
397
+ let(:building) do
398
+ Building.create!(contractors: [ contractor1 ])
399
+ end
400
+
401
+ let(:more_contractors) { building.contractors + [ contractor2 ] }
402
+
403
+ let(:modified_building) do
404
+ building.tap do
405
+ building.assign_attributes contractors: more_contractors
406
+ end
407
+ end
408
+
409
+ let(:reloaded_building) { modified_building.reload }
410
+
411
+ it 'resets delayed_atomic_sets' do
412
+ expect(modified_building.delayed_atomic_sets).not_to be_empty
413
+ expect(reloaded_building.delayed_atomic_sets).to be_empty
414
+ end
415
+ end
416
+
393
417
  context "when embedded document is nil" do
394
418
 
395
419
  let(:palette) do
@@ -59,3 +59,17 @@ end
59
59
  class SmNotSharded
60
60
  include Mongoid::Document
61
61
  end
62
+
63
+ class SmReviewAuthor
64
+ include Mongoid::Document
65
+ embedded_in :review, class_name: "SmReview", touch: false
66
+ field :name, type: String
67
+ end
68
+
69
+ class SmReview
70
+ include Mongoid::Document
71
+
72
+ embeds_one :author, class_name: "SmReviewAuthor"
73
+
74
+ shard_key "author.name" => 1
75
+ end