mongoid 7.5.1 → 7.5.4
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/Rakefile +25 -0
- data/lib/mongoid/association/embedded/batchable.rb +20 -3
- data/lib/mongoid/atomic/paths/embedded/many.rb +19 -0
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/config.rb +6 -0
- data/lib/mongoid/contextual/mongo.rb +24 -7
- data/lib/mongoid/criteria/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/document.rb +8 -1
- data/lib/mongoid/persistence_context.rb +57 -6
- data/lib/mongoid/shardable.rb +35 -11
- data/lib/mongoid/version.rb +1 -1
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +21 -0
- data/spec/mongoid/association/embedded/embeds_many_models.rb +121 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +30 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +20 -0
- data/spec/mongoid/attributes_spec.rb +44 -0
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/clients_spec.rb +30 -0
- data/spec/mongoid/config_spec.rb +7 -0
- data/spec/mongoid/contextual/mongo_spec.rb +23 -3
- data/spec/mongoid/criteria/queryable/selector_spec.rb +75 -2
- data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
- data/spec/mongoid/persistence_context_spec.rb +26 -1
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +157 -51
- data/spec/mongoid_spec.rb +7 -1
- data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
- data/spec/shared/shlib/server.sh +5 -5
- data.tar.gz.sig +0 -0
- metadata +632 -628
- metadata.gz.sig +3 -2
|
@@ -1675,6 +1675,50 @@ describe Mongoid::Attributes do
|
|
|
1675
1675
|
end
|
|
1676
1676
|
end
|
|
1677
1677
|
end
|
|
1678
|
+
|
|
1679
|
+
context "when comparing the object_ids of the written value" do
|
|
1680
|
+
config_override :legacy_attributes, false
|
|
1681
|
+
|
|
1682
|
+
before do
|
|
1683
|
+
Person.create!
|
|
1684
|
+
end
|
|
1685
|
+
|
|
1686
|
+
let(:person) do
|
|
1687
|
+
Person.first
|
|
1688
|
+
end
|
|
1689
|
+
|
|
1690
|
+
context "when the field is not resizable" do
|
|
1691
|
+
let(:test) do
|
|
1692
|
+
person.write_attribute(:test, "aliased field to test")
|
|
1693
|
+
end
|
|
1694
|
+
|
|
1695
|
+
it "has the same object_id as the attributes hash value" do
|
|
1696
|
+
expect(test.object_id).to eq(person.test.object_id)
|
|
1697
|
+
end
|
|
1698
|
+
end
|
|
1699
|
+
|
|
1700
|
+
context "when the field is resizable" do
|
|
1701
|
+
|
|
1702
|
+
let(:arrays) do
|
|
1703
|
+
person.write_attribute(:arrays, [])
|
|
1704
|
+
end
|
|
1705
|
+
|
|
1706
|
+
it "has the same object_id as the attributes hash value" do
|
|
1707
|
+
expect(arrays.object_id).to eq(person.arrays.object_id)
|
|
1708
|
+
end
|
|
1709
|
+
end
|
|
1710
|
+
|
|
1711
|
+
context "when the field is a HABTM foreign key array" do
|
|
1712
|
+
|
|
1713
|
+
let(:preference_ids) do
|
|
1714
|
+
person.write_attribute(:preference_ids, [])
|
|
1715
|
+
end
|
|
1716
|
+
|
|
1717
|
+
it "has the same object_id as the attributes hash value" do
|
|
1718
|
+
expect(preference_ids.object_id).to eq(person.preference_ids.object_id)
|
|
1719
|
+
end
|
|
1720
|
+
end
|
|
1721
|
+
end
|
|
1678
1722
|
end
|
|
1679
1723
|
|
|
1680
1724
|
describe "#typed_value_for" do
|
|
@@ -45,7 +45,7 @@ describe Mongoid::Cacheable do
|
|
|
45
45
|
context "with the default cache_timestamp_format" do
|
|
46
46
|
|
|
47
47
|
let!(:updated_at) do
|
|
48
|
-
document.updated_at.utc.
|
|
48
|
+
document.updated_at.utc.to_formatted_s(:nsec)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
51
|
it "has the id and updated_at key name" do
|
|
@@ -64,7 +64,7 @@ describe Mongoid::Cacheable do
|
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
let!(:updated_at) do
|
|
67
|
-
document.updated_at.utc.
|
|
67
|
+
document.updated_at.utc.to_formatted_s(:number)
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
it "has the id and updated_at key name" do
|
|
@@ -103,7 +103,7 @@ describe Mongoid::Cacheable do
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
let!(:updated_at) do
|
|
106
|
-
agent.updated_at.utc.
|
|
106
|
+
agent.updated_at.utc.to_formatted_s(:nsec)
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
it "has the id and updated_at key name" do
|
|
@@ -1012,6 +1012,36 @@ describe Mongoid::Clients do
|
|
|
1012
1012
|
end
|
|
1013
1013
|
end
|
|
1014
1014
|
end
|
|
1015
|
+
|
|
1016
|
+
context 'when requesting named client' do
|
|
1017
|
+
let(:secondary_client) do
|
|
1018
|
+
double(Mongo::Client).tap do |client|
|
|
1019
|
+
allow(client).to receive(:cluster).and_return(double("cluster"))
|
|
1020
|
+
end
|
|
1021
|
+
end
|
|
1022
|
+
|
|
1023
|
+
before do
|
|
1024
|
+
expect(Mongoid::Clients::Factory).to receive(:create)
|
|
1025
|
+
.with(:secondary)
|
|
1026
|
+
.and_return(secondary_client)
|
|
1027
|
+
end
|
|
1028
|
+
|
|
1029
|
+
after do
|
|
1030
|
+
Mongoid::Clients.clients.delete(:secondary)
|
|
1031
|
+
end
|
|
1032
|
+
|
|
1033
|
+
it 'does not close the client' do
|
|
1034
|
+
expect(secondary_client).not_to receive(:close)
|
|
1035
|
+
|
|
1036
|
+
Band.with(client: :default) do |klass|
|
|
1037
|
+
klass.mongo_client
|
|
1038
|
+
end
|
|
1039
|
+
|
|
1040
|
+
Band.with(client: :secondary) do |klass|
|
|
1041
|
+
klass.mongo_client
|
|
1042
|
+
end
|
|
1043
|
+
end
|
|
1044
|
+
end
|
|
1015
1045
|
end
|
|
1016
1046
|
|
|
1017
1047
|
context "when overriding the default database" do
|
data/spec/mongoid/config_spec.rb
CHANGED
|
@@ -335,6 +335,13 @@ describe Mongoid::Config do
|
|
|
335
335
|
it_behaves_like "a config option"
|
|
336
336
|
end
|
|
337
337
|
|
|
338
|
+
context 'when setting the legacy_attributes option in the config' do
|
|
339
|
+
let(:option) { :legacy_attributes }
|
|
340
|
+
let(:default) { true }
|
|
341
|
+
|
|
342
|
+
it_behaves_like "a config option"
|
|
343
|
+
end
|
|
344
|
+
|
|
338
345
|
describe "#load!" do
|
|
339
346
|
|
|
340
347
|
before(:all) do
|
|
@@ -1554,9 +1554,9 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1554
1554
|
expect(context.send(method)).to eq(depeche_mode)
|
|
1555
1555
|
end
|
|
1556
1556
|
|
|
1557
|
-
context
|
|
1557
|
+
context "when calling ##{method}" do
|
|
1558
1558
|
|
|
1559
|
-
it 'returns the
|
|
1559
|
+
it 'returns the requested document, sorted by _id' do
|
|
1560
1560
|
expect(context.send(method)).to eq(depeche_mode)
|
|
1561
1561
|
expect(context.last).to eq(rolling_stones)
|
|
1562
1562
|
end
|
|
@@ -1571,7 +1571,7 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1571
1571
|
expect(context.send(method, opts)).to eq(depeche_mode)
|
|
1572
1572
|
end
|
|
1573
1573
|
|
|
1574
|
-
context
|
|
1574
|
+
context "when calling ##{method}" do
|
|
1575
1575
|
|
|
1576
1576
|
it 'doesn\'t apply a sort on _id' do
|
|
1577
1577
|
expect(context.send(method, opts)).to eq(depeche_mode)
|
|
@@ -1883,6 +1883,16 @@ describe Mongoid::Contextual::Mongo do
|
|
|
1883
1883
|
end
|
|
1884
1884
|
end
|
|
1885
1885
|
|
|
1886
|
+
context "when given an empty hash" do
|
|
1887
|
+
let(:context) { described_class.new(criteria) }
|
|
1888
|
+
let(:criteria) { Band.criteria }
|
|
1889
|
+
let(:docs) { context.send(method, {}) }
|
|
1890
|
+
|
|
1891
|
+
it "behaves as if limit is nil" do
|
|
1892
|
+
expect(docs).to eq(depeche_mode)
|
|
1893
|
+
end
|
|
1894
|
+
end
|
|
1895
|
+
|
|
1886
1896
|
context "when calling #first then #last" do
|
|
1887
1897
|
|
|
1888
1898
|
let(:context) do
|
|
@@ -2358,6 +2368,16 @@ describe Mongoid::Contextual::Mongo do
|
|
|
2358
2368
|
end
|
|
2359
2369
|
end
|
|
2360
2370
|
end
|
|
2371
|
+
|
|
2372
|
+
context "when given an empty hash" do
|
|
2373
|
+
let(:context) { described_class.new(criteria) }
|
|
2374
|
+
let(:criteria) { Band.criteria }
|
|
2375
|
+
let(:docs) { context.last({}) }
|
|
2376
|
+
|
|
2377
|
+
it "behaves as if limit is nil" do
|
|
2378
|
+
expect(docs).to eq(rolling_stones)
|
|
2379
|
+
end
|
|
2380
|
+
end
|
|
2361
2381
|
end
|
|
2362
2382
|
|
|
2363
2383
|
describe "#initialize" do
|
|
@@ -44,7 +44,7 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
context "when selector contains a $nin" do
|
|
47
|
+
context "when selector contains a $nin string" do
|
|
48
48
|
|
|
49
49
|
let(:initial) do
|
|
50
50
|
{ "$nin" => ["foo"] }
|
|
@@ -72,7 +72,35 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
context "when selector contains a $
|
|
75
|
+
context "when selector contains a $nin symbol" do
|
|
76
|
+
|
|
77
|
+
let(:initial) do
|
|
78
|
+
{ :$nin => ["foo"] }
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
before do
|
|
82
|
+
selector["field"] = initial
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
context "when merging in a new $nin" do
|
|
86
|
+
|
|
87
|
+
let(:other) do
|
|
88
|
+
{ "field" => { :$nin => ["bar"] } }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
before do
|
|
92
|
+
selector.merge!(other)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "combines the two $nin queries into one" do
|
|
96
|
+
expect(selector).to eq({
|
|
97
|
+
"field" => { :$nin => ["foo", "bar"] }
|
|
98
|
+
})
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "when selector contains a $in string" do
|
|
76
104
|
|
|
77
105
|
let(:initial) do
|
|
78
106
|
{ "$in" => [1, 2] }
|
|
@@ -117,6 +145,51 @@ describe Mongoid::Criteria::Queryable::Selector do
|
|
|
117
145
|
end
|
|
118
146
|
end
|
|
119
147
|
|
|
148
|
+
context "when selector contains a $in symbol" do
|
|
149
|
+
|
|
150
|
+
let(:initial) do
|
|
151
|
+
{ :$in => [1, 2] }
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
before do
|
|
155
|
+
selector["field"] = initial
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
context "when merging in a new $in with an intersecting value" do
|
|
159
|
+
|
|
160
|
+
let(:other) do
|
|
161
|
+
{ "field" => { :$in => [1] } }
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
before do
|
|
165
|
+
selector.merge!(other)
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
it "intersects the $in values" do
|
|
169
|
+
expect(selector).to eq({
|
|
170
|
+
"field" => { :$in => [1] }
|
|
171
|
+
})
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
context "when merging in a new $in with no intersecting values" do
|
|
176
|
+
|
|
177
|
+
let(:other) do
|
|
178
|
+
{ "field" => { :$in => [3] } }
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
before do
|
|
182
|
+
selector.merge!(other)
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
it "intersects the $in values" do
|
|
186
|
+
expect(selector).to eq({
|
|
187
|
+
"field" => { :$in => [] }
|
|
188
|
+
})
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
|
|
120
193
|
context "when selector is not nested" do
|
|
121
194
|
|
|
122
195
|
before do
|
|
@@ -210,7 +210,79 @@ describe Mongoid::Criteria::Queryable::Storable do
|
|
|
210
210
|
}
|
|
211
211
|
end
|
|
212
212
|
end
|
|
213
|
+
|
|
214
|
+
context 'when value is a hash combine values with different operator keys' do
|
|
215
|
+
let(:base) do
|
|
216
|
+
query.add_field_expression('foo', {'$in' => ['bar']})
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
let(:modified) do
|
|
220
|
+
base.add_field_expression('foo', {'$nin' => ['zoom']})
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
it 'combines the conditions using $and' do
|
|
224
|
+
modified.selector.should == {
|
|
225
|
+
'foo' => {
|
|
226
|
+
'$in' => ['bar'],
|
|
227
|
+
'$nin' => ['zoom']
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
context 'when value is a hash with symbol operator key combine values with different operator keys' do
|
|
234
|
+
let(:base) do
|
|
235
|
+
query.add_field_expression('foo', {:$in => ['bar']})
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
let(:modified) do
|
|
239
|
+
base.add_field_expression('foo', {:$nin => ['zoom']})
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
it 'combines the conditions using $and' do
|
|
243
|
+
modified.selector.should == {
|
|
244
|
+
'foo' => {
|
|
245
|
+
:$in => ['bar'],
|
|
246
|
+
:$nin => ['zoom']
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
context 'when value is a hash add values with same operator keys using $and' do
|
|
253
|
+
let(:base) do
|
|
254
|
+
query.add_field_expression('foo', {'$in' => ['bar']})
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
let(:modified) do
|
|
258
|
+
base.add_field_expression('foo', {'$in' => ['zoom']})
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
it 'adds the new condition using $and' do
|
|
262
|
+
modified.selector.should == {
|
|
263
|
+
'foo' => {'$in' => ['bar']},
|
|
264
|
+
'$and' => ['foo' => {'$in' => ['zoom']}]
|
|
265
|
+
}
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
context 'when value is a hash with symbol operator key add values with same operator keys using $and' do
|
|
270
|
+
let(:base) do
|
|
271
|
+
query.add_field_expression('foo', {:$in => ['bar']})
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
let(:modified) do
|
|
275
|
+
base.add_field_expression('foo', {:$in => ['zoom']})
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
it 'adds the new condition using $and' do
|
|
279
|
+
modified.selector.should == {
|
|
280
|
+
'foo' => {:$in => ['bar']},
|
|
281
|
+
'$and' => ['foo' => {:$in => ['zoom']}]
|
|
282
|
+
}
|
|
283
|
+
end
|
|
213
284
|
end
|
|
285
|
+
end
|
|
214
286
|
|
|
215
287
|
describe '#add_operator_expression' do
|
|
216
288
|
let(:query_method) { :add_operator_expression }
|
|
@@ -39,7 +39,6 @@ describe Mongoid::PersistenceContext do
|
|
|
39
39
|
end
|
|
40
40
|
end
|
|
41
41
|
|
|
42
|
-
|
|
43
42
|
describe '.get' do
|
|
44
43
|
|
|
45
44
|
let(:options) do
|
|
@@ -134,6 +133,32 @@ describe Mongoid::PersistenceContext do
|
|
|
134
133
|
end
|
|
135
134
|
end
|
|
136
135
|
end
|
|
136
|
+
|
|
137
|
+
context 'with reusable client' do
|
|
138
|
+
let(:options) do
|
|
139
|
+
{client: :some_client}
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
let(:cluster) do
|
|
143
|
+
double(Mongo::Cluster)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
let(:client) do
|
|
147
|
+
double(Mongo::Client).tap do |client|
|
|
148
|
+
allow(client).to receive(:cluster).and_return(cluster)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
before do
|
|
153
|
+
expect(Mongoid::Clients).to receive(:with_name).with(:some_client).and_return(client)
|
|
154
|
+
expect(client).not_to receive(:close)
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it 'does not close the client' do
|
|
158
|
+
described_class.set(object, options)
|
|
159
|
+
described_class.clear(object, cluster.dup)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
137
162
|
end
|
|
138
163
|
|
|
139
164
|
describe '#initialize' 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
|