mongoid 4.0.2 → 5.0.0.beta
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
- data/CHANGELOG.md +66 -1
- data/README.md +14 -13
- data/lib/config/locales/en.yml +28 -28
- data/lib/mongoid.rb +28 -21
- data/lib/mongoid/atomic.rb +2 -4
- data/lib/mongoid/attributes.rb +7 -7
- data/lib/mongoid/attributes/processing.rb +4 -1
- data/lib/mongoid/attributes/readonly.rb +2 -2
- data/lib/mongoid/changeable.rb +4 -6
- data/lib/mongoid/clients.rb +142 -0
- data/lib/mongoid/clients/factory.rb +78 -0
- data/lib/mongoid/{sessions → clients}/options.rb +30 -19
- data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
- data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
- data/lib/mongoid/clients/validators.rb +2 -0
- data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
- data/lib/mongoid/composable.rb +3 -3
- data/lib/mongoid/config.rb +39 -41
- data/lib/mongoid/config/environment.rb +1 -1
- data/lib/mongoid/config/validators.rb +1 -1
- data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +11 -11
- data/lib/mongoid/contextual/command.rb +9 -6
- data/lib/mongoid/contextual/geo_near.rb +17 -1
- data/lib/mongoid/contextual/map_reduce.rb +12 -11
- data/lib/mongoid/contextual/memory.rb +2 -5
- data/lib/mongoid/contextual/mongo.rb +92 -82
- data/lib/mongoid/contextual/none.rb +13 -0
- data/lib/mongoid/copyable.rb +6 -1
- data/lib/mongoid/criteria.rb +36 -3
- data/lib/mongoid/document.rb +3 -4
- data/lib/mongoid/errors.rb +6 -6
- data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
- data/lib/mongoid/errors/no_client_config.rb +22 -0
- data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
- data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
- data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
- data/lib/mongoid/errors/no_default_client.rb +23 -0
- data/lib/mongoid/extensions/hash.rb +5 -1
- data/lib/mongoid/extensions/object.rb +3 -2
- data/lib/mongoid/extensions/set.rb +5 -5
- data/lib/mongoid/factory.rb +4 -2
- data/lib/mongoid/fields.rb +7 -2
- data/lib/mongoid/findable.rb +4 -1
- data/lib/mongoid/indexable.rb +15 -9
- data/lib/mongoid/persistable.rb +1 -2
- data/lib/mongoid/persistable/creatable.rb +2 -2
- data/lib/mongoid/persistable/deletable.rb +3 -3
- data/lib/mongoid/persistable/incrementable.rb +1 -1
- data/lib/mongoid/persistable/logical.rb +1 -1
- data/lib/mongoid/persistable/poppable.rb +1 -1
- data/lib/mongoid/persistable/pullable.rb +2 -2
- data/lib/mongoid/persistable/pushable.rb +2 -2
- data/lib/mongoid/persistable/renamable.rb +1 -1
- data/lib/mongoid/persistable/settable.rb +1 -1
- data/lib/mongoid/persistable/unsettable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/query_cache.rb +98 -104
- data/lib/mongoid/railtie.rb +1 -21
- data/lib/mongoid/railties/database.rake +1 -1
- data/lib/mongoid/relations/builders.rb +3 -1
- data/lib/mongoid/relations/counter_cache.rb +1 -1
- data/lib/mongoid/relations/embedded/batchable.rb +3 -10
- data/lib/mongoid/relations/embedded/many.rb +4 -2
- data/lib/mongoid/relations/many.rb +1 -0
- data/lib/mongoid/relations/proxy.rb +6 -6
- data/lib/mongoid/relations/referenced/many.rb +2 -1
- data/lib/mongoid/relations/targets/enumerable.rb +11 -11
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +6 -17
- data/lib/mongoid/selectable.rb +1 -36
- data/lib/mongoid/serializable.rb +2 -2
- data/lib/mongoid/stateful.rb +0 -1
- data/lib/mongoid/tasks/database.rake +2 -2
- data/lib/mongoid/tasks/database.rb +23 -16
- data/lib/mongoid/threaded.rb +54 -33
- data/lib/mongoid/threaded/lifecycle.rb +21 -16
- data/lib/mongoid/traversable.rb +16 -1
- data/lib/mongoid/validatable.rb +1 -1
- data/lib/mongoid/validatable/queryable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +3 -20
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
- data/lib/rails/mongoid.rb +2 -2
- data/spec/app/models/audio.rb +1 -1
- data/spec/app/models/band.rb +1 -0
- data/spec/app/models/company.rb +5 -0
- data/spec/app/models/label.rb +7 -0
- data/spec/app/models/pub.rb +6 -0
- data/spec/app/models/staff.rb +7 -0
- data/spec/app/models/store_as_dup_test1.rb +5 -0
- data/spec/app/models/store_as_dup_test2.rb +5 -0
- data/spec/config/mongoid.yml +7 -25
- data/spec/mongoid/atomic/paths_spec.rb +3 -11
- data/spec/mongoid/attributes/nested_spec.rb +16 -16
- data/spec/mongoid/attributes/readonly_spec.rb +80 -18
- data/spec/mongoid/attributes_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +70 -0
- data/spec/mongoid/clients/factory_spec.rb +284 -0
- data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
- data/spec/mongoid/clients_spec.rb +739 -0
- data/spec/mongoid/config/environment_spec.rb +14 -11
- data/spec/mongoid/config_spec.rb +33 -48
- data/spec/mongoid/contextual/atomic_spec.rb +1 -17
- data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
- data/spec/mongoid/contextual/mongo_spec.rb +26 -83
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +35 -1
- data/spec/mongoid/criteria/findable_spec.rb +197 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
- data/spec/mongoid/criteria_spec.rb +74 -91
- data/spec/mongoid/document_spec.rb +1 -1
- data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
- data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
- data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
- data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
- data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
- data/spec/mongoid/fields/localized_spec.rb +1 -0
- data/spec/mongoid/fields_spec.rb +1 -0
- data/spec/mongoid/findable_spec.rb +2 -23
- data/spec/mongoid/indexable_spec.rb +12 -8
- data/spec/mongoid/interceptable_spec.rb +15 -0
- data/spec/mongoid/persistable/settable_spec.rb +16 -0
- data/spec/mongoid/persistable/updatable_spec.rb +3 -2
- data/spec/mongoid/persistable_spec.rb +4 -4
- data/spec/mongoid/query_cache_spec.rb +13 -8
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
- data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
- data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
- data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
- data/spec/mongoid/relations/proxy_spec.rb +28 -0
- data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
- data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
- data/spec/mongoid/reloadable_spec.rb +6 -6
- data/spec/mongoid/scopable_spec.rb +41 -28
- data/spec/mongoid/selectable_spec.rb +6 -16
- data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
- data/spec/mongoid/tasks/database_spec.rb +2 -2
- data/spec/mongoid/threaded_spec.rb +0 -7
- data/spec/mongoid/traversable_spec.rb +2 -2
- data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
- data/spec/mongoid_spec.rb +13 -15
- data/spec/rails/mongoid_spec.rb +13 -4
- data/spec/spec_helper.rb +44 -27
- data/spec/support/authorization.rb +12 -0
- data/spec/support/expectations.rb +14 -0
- metadata +52 -59
- data/lib/mongoid/contextual/find_and_modify.rb +0 -69
- data/lib/mongoid/contextual/text_search.rb +0 -178
- data/lib/mongoid/criteria/#findable.rb# +0 -141
- data/lib/mongoid/errors/no_default_session.rb +0 -23
- data/lib/mongoid/errors/no_session_config.rb +0 -22
- data/lib/mongoid/log_subscriber.rb +0 -55
- data/lib/mongoid/positional.rb +0 -71
- data/lib/mongoid/sessions.rb +0 -125
- data/lib/mongoid/sessions/factory.rb +0 -131
- data/lib/mongoid/sessions/mongo_uri.rb +0 -93
- data/lib/mongoid/sessions/validators.rb +0 -2
- data/lib/mongoid/support/query_counter.rb +0 -23
- data/spec/helpers.rb +0 -18
- data/spec/mongoid/#atomic_spec.rb# +0 -365
- data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
- data/spec/mongoid/contextual/text_search_spec.rb +0 -209
- data/spec/mongoid/log_subscriber_spec.rb +0 -75
- data/spec/mongoid/positional_spec.rb +0 -222
- data/spec/mongoid/sessions/factory_spec.rb +0 -333
- data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
- data/spec/mongoid/sessions_spec.rb +0 -1252
data/spec/helpers.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
require 'mongoid/support/query_counter'
|
2
|
-
|
3
|
-
module Mongoid
|
4
|
-
module SpecHelpers
|
5
|
-
def expect_query(number, &block)
|
6
|
-
query_counter = Mongoid::QueryCounter.new
|
7
|
-
query_counter.instrument(&block)
|
8
|
-
expect(query_counter.events.size).to(eq(number), %[
|
9
|
-
Expected to receive #{number} queries, it received #{query_counter.events.size}
|
10
|
-
#{query_counter.inspect}
|
11
|
-
])
|
12
|
-
end
|
13
|
-
|
14
|
-
def expect_no_queries(&block)
|
15
|
-
expect_query(0, &block)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,365 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mongoid::Atomic do
|
4
|
-
|
5
|
-
describe "#add_atomic_pull" do
|
6
|
-
|
7
|
-
let!(:person) do
|
8
|
-
Person.create
|
9
|
-
end
|
10
|
-
|
11
|
-
let(:address) do
|
12
|
-
person.addresses.create
|
13
|
-
end
|
14
|
-
|
15
|
-
let(:location) do
|
16
|
-
address.locations.create
|
17
|
-
end
|
18
|
-
|
19
|
-
before do
|
20
|
-
person.add_atomic_pull(address)
|
21
|
-
end
|
22
|
-
|
23
|
-
it "adds the document to the delayed atomic pulls" do
|
24
|
-
expect(person.delayed_atomic_pulls["addresses"]).to eq([ address ])
|
25
|
-
end
|
26
|
-
|
27
|
-
it "flags the document for destruction" do
|
28
|
-
expect(address).to be_flagged_for_destroy
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "#add_atomic_unset" do
|
33
|
-
|
34
|
-
let!(:person) do
|
35
|
-
Person.new
|
36
|
-
end
|
37
|
-
|
38
|
-
let(:name) do
|
39
|
-
person.build_name
|
40
|
-
end
|
41
|
-
|
42
|
-
before do
|
43
|
-
person.add_atomic_unset(name)
|
44
|
-
end
|
45
|
-
|
46
|
-
it "adds the document to the delayed atomic unsets" do
|
47
|
-
expect(person.delayed_atomic_unsets["name"]).to eq([ name ])
|
48
|
-
end
|
49
|
-
|
50
|
-
it "flags the document for destruction" do
|
51
|
-
expect(name).to be_flagged_for_destroy
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe "#atomic_updates" do
|
56
|
-
|
57
|
-
context "when the document is persisted" do
|
58
|
-
|
59
|
-
let(:person) do
|
60
|
-
Person.create
|
61
|
-
end
|
62
|
-
|
63
|
-
context "when the document is modified" do
|
64
|
-
|
65
|
-
before do
|
66
|
-
person.title = "Sir"
|
67
|
-
end
|
68
|
-
|
69
|
-
it "returns the atomic updates" do
|
70
|
-
expect(person.atomic_updates).to eq({ "$set" => { "title" => "Sir" }})
|
71
|
-
end
|
72
|
-
|
73
|
-
context "when an embeds many child is added" do
|
74
|
-
|
75
|
-
let!(:address) do
|
76
|
-
person.addresses.build(street: "Oxford St")
|
77
|
-
end
|
78
|
-
|
79
|
-
it "returns a $set and $pushAll for modifications" do
|
80
|
-
expect(person.atomic_updates).to eq(
|
81
|
-
{
|
82
|
-
"$set" => { "title" => "Sir" },
|
83
|
-
"$pushAll" => { "addresses" => [
|
84
|
-
{ "_id" => "oxford-st", "street" => "Oxford St" }
|
85
|
-
]}
|
86
|
-
}
|
87
|
-
)
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "when an embeds one child is added" do
|
92
|
-
|
93
|
-
let!(:name) do
|
94
|
-
person.build_name(first_name: "Lionel")
|
95
|
-
end
|
96
|
-
|
97
|
-
it "returns a $set for modifications" do
|
98
|
-
expect(person.atomic_updates).to eq(
|
99
|
-
{
|
100
|
-
"$set" => {
|
101
|
-
"title" => "Sir",
|
102
|
-
"name" => { "_id" => "Lionel-", "first_name" => "Lionel" }
|
103
|
-
}
|
104
|
-
}
|
105
|
-
)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
|
109
|
-
context "when an existing embeds many gets modified" do
|
110
|
-
|
111
|
-
let!(:address) do
|
112
|
-
person.addresses.create(street: "Oxford St")
|
113
|
-
end
|
114
|
-
|
115
|
-
before do
|
116
|
-
address.street = "Bond St"
|
117
|
-
end
|
118
|
-
|
119
|
-
context "when asking for the updates from the root" do
|
120
|
-
|
121
|
-
it "returns the $set with correct position and modifications" do
|
122
|
-
expect(person.atomic_updates).to eq(
|
123
|
-
{ "$set" => { "title" => "Sir", "addresses.0.street" => "Bond St" }}
|
124
|
-
)
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
context "when asking for the updates from the child" do
|
129
|
-
|
130
|
-
it "returns the $set with correct position and modifications" do
|
131
|
-
expect(address.atomic_updates).to eq(
|
132
|
-
{ "$set" => { "addresses.0.street" => "Bond St" }}
|
133
|
-
)
|
134
|
-
end
|
135
|
-
end
|
136
|
-
|
137
|
-
context "when an existing 2nd level embedded child gets modified" do
|
138
|
-
|
139
|
-
let!(:location) do
|
140
|
-
address.locations.create(name: "Home")
|
141
|
-
end
|
142
|
-
|
143
|
-
before do
|
144
|
-
location.name = "Work"
|
145
|
-
end
|
146
|
-
|
147
|
-
context "when asking for the updates from the root" do
|
148
|
-
|
149
|
-
it "returns the $set with correct positions and modifications" do
|
150
|
-
expect(person.atomic_updates).to eq(
|
151
|
-
{ "$set" => {
|
152
|
-
"title" => "Sir",
|
153
|
-
"addresses.0.street" => "Bond St",
|
154
|
-
"addresses.0.locations.0.name" => "Work" }
|
155
|
-
}
|
156
|
-
)
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
context "when asking for the updates from the 1st level child" do
|
161
|
-
|
162
|
-
it "returns the $set with correct positions and modifications" do
|
163
|
-
expect(address.atomic_updates).to eq(
|
164
|
-
{ "$set" => {
|
165
|
-
"addresses.0.street" => "Bond St",
|
166
|
-
"addresses.0.locations.0.name" => "Work" }
|
167
|
-
}
|
168
|
-
)
|
169
|
-
end
|
170
|
-
end
|
171
|
-
|
172
|
-
context "when asking for the updates from the 2nd level child" do
|
173
|
-
|
174
|
-
it "returns the $set with correct positions and modifications" do
|
175
|
-
expect(location.atomic_updates).to eq(
|
176
|
-
{ "$set" => {
|
177
|
-
"addresses.0.locations.0.name" => "Work" }
|
178
|
-
}
|
179
|
-
)
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
context "when a 2nd level embedded child gets added" do
|
185
|
-
|
186
|
-
let!(:location) do
|
187
|
-
address.locations.build(name: "Home")
|
188
|
-
end
|
189
|
-
|
190
|
-
context "when asking for the updates from the root" do
|
191
|
-
|
192
|
-
it "returns the $set with correct positions and modifications" do
|
193
|
-
expect(person.atomic_updates).to eq(
|
194
|
-
{
|
195
|
-
"$set" => {
|
196
|
-
"title" => "Sir",
|
197
|
-
"addresses.0.street" => "Bond St"
|
198
|
-
},
|
199
|
-
conflicts: {
|
200
|
-
"$pushAll" => {
|
201
|
-
"addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
)
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
context "when asking for the updates from the 1st level child" do
|
210
|
-
|
211
|
-
it "returns the $set with correct positions and modifications" do
|
212
|
-
expect(address.atomic_updates).to eq(
|
213
|
-
{
|
214
|
-
"$set" => {
|
215
|
-
"addresses.0.street" => "Bond St"
|
216
|
-
},
|
217
|
-
conflicts: {
|
218
|
-
"$pushAll" => {
|
219
|
-
"addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
|
220
|
-
}
|
221
|
-
}
|
222
|
-
}
|
223
|
-
)
|
224
|
-
end
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context "when an embedded child gets unset" do
|
229
|
-
|
230
|
-
before do
|
231
|
-
person.attributes = { addresses: nil }
|
232
|
-
end
|
233
|
-
|
234
|
-
let(:updates) do
|
235
|
-
person.atomic_updates
|
236
|
-
end
|
237
|
-
|
238
|
-
it "returns the $set for the first level and $unset for other." do
|
239
|
-
expect(updates).to eq({
|
240
|
-
"$unset" => { "addresses" => true },
|
241
|
-
"$set" => { "title" => "Sir" }
|
242
|
-
})
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
context "when adding a new second level child" do
|
247
|
-
|
248
|
-
let!(:new_address) do
|
249
|
-
person.addresses.build(street: "Another")
|
250
|
-
end
|
251
|
-
|
252
|
-
let!(:location) do
|
253
|
-
new_address.locations.build(name: "Home")
|
254
|
-
end
|
255
|
-
|
256
|
-
context "when asking for the updates from the root document" do
|
257
|
-
|
258
|
-
it "returns the $set for 1st level and other for the 2nd level" do
|
259
|
-
expect(person.atomic_updates).to eq(
|
260
|
-
{
|
261
|
-
"$set" => {
|
262
|
-
"title" => "Sir",
|
263
|
-
"addresses.0.street" => "Bond St"
|
264
|
-
},
|
265
|
-
conflicts: {
|
266
|
-
"$pushAll" => {
|
267
|
-
"addresses" => [{
|
268
|
-
"_id" => new_address.id,
|
269
|
-
"street" => "Another",
|
270
|
-
"locations" => [
|
271
|
-
"_id" => location.id,
|
272
|
-
"name" => "Home"
|
273
|
-
]
|
274
|
-
}]
|
275
|
-
}
|
276
|
-
}
|
277
|
-
}
|
278
|
-
)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
context "when asking for the updates from the 1st level document" do
|
283
|
-
|
284
|
-
it "returns the $set for 1st level and other for the 2nd level" do
|
285
|
-
expect(address.atomic_updates).to eq(
|
286
|
-
{ "$set" => { "addresses.0.street" => "Bond St" }}
|
287
|
-
)
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
context "when adding a new child beetween two existing and updating one of them" do
|
293
|
-
|
294
|
-
let!(:new_address) do
|
295
|
-
person.addresses.build(street: "Ipanema")
|
296
|
-
end
|
297
|
-
|
298
|
-
let!(:location) do
|
299
|
-
new_address.locations.build(name: "Home")
|
300
|
-
end
|
301
|
-
|
302
|
-
before do
|
303
|
-
person.addresses[0] = new_address
|
304
|
-
person.addresses[1] = address
|
305
|
-
end
|
306
|
-
|
307
|
-
it "returns the $set for 1st and 2nd level and other for the 3nd level" do
|
308
|
-
expect(person.atomic_updates).to eq(
|
309
|
-
{
|
310
|
-
"$set" => {
|
311
|
-
"title" => "Sir"
|
312
|
-
},
|
313
|
-
"$pushAll" => {
|
314
|
-
"addresses" => [{
|
315
|
-
"_id" => new_address.id,
|
316
|
-
"street" => "Ipanema",
|
317
|
-
"locations" => [
|
318
|
-
"_id" => location.id,
|
319
|
-
"name" => "Home"
|
320
|
-
]
|
321
|
-
}]
|
322
|
-
},
|
323
|
-
conflicts: {
|
324
|
-
"$set" => { "addresses.0.street"=>"Bond St" }
|
325
|
-
}
|
326
|
-
}
|
327
|
-
)
|
328
|
-
end
|
329
|
-
end
|
330
|
-
end
|
331
|
-
|
332
|
-
context "when adding new embedded docs at multiple levels" do
|
333
|
-
|
334
|
-
let!(:address) do
|
335
|
-
person.addresses.build(street: "Another")
|
336
|
-
end
|
337
|
-
|
338
|
-
let!(:location) do
|
339
|
-
address.locations.build(name: "Home")
|
340
|
-
end
|
341
|
-
|
342
|
-
it "returns the proper $sets and $pushAlls for all levels" do
|
343
|
-
expect(person.atomic_updates).to eq(
|
344
|
-
{
|
345
|
-
"$set" => {
|
346
|
-
"title" => "Sir",
|
347
|
-
},
|
348
|
-
"$pushAll" => {
|
349
|
-
"addresses" => [{
|
350
|
-
"_id" => address.id,
|
351
|
-
"street" => "Another",
|
352
|
-
"locations" => [
|
353
|
-
"_id" => location.id,
|
354
|
-
"name" => "Home"
|
355
|
-
]
|
356
|
-
}]
|
357
|
-
}
|
358
|
-
}
|
359
|
-
)
|
360
|
-
end
|
361
|
-
end
|
362
|
-
end
|
363
|
-
end
|
364
|
-
end
|
365
|
-
end
|
@@ -1,220 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mongoid::Contextual::FindAndModify do
|
4
|
-
|
5
|
-
describe "#result" do
|
6
|
-
|
7
|
-
let!(:depeche) do
|
8
|
-
Band.create(name: "Depeche Mode")
|
9
|
-
end
|
10
|
-
|
11
|
-
let!(:tool) do
|
12
|
-
Band.create(name: "Tool")
|
13
|
-
end
|
14
|
-
|
15
|
-
let!(:collection) do
|
16
|
-
Band.collection
|
17
|
-
end
|
18
|
-
|
19
|
-
context "when the selector matches" do
|
20
|
-
|
21
|
-
context "when not providing options" do
|
22
|
-
|
23
|
-
let(:criteria) do
|
24
|
-
Band.where(name: "Depeche Mode")
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:context) do
|
28
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }})
|
29
|
-
end
|
30
|
-
|
31
|
-
let!(:result) do
|
32
|
-
context.result
|
33
|
-
end
|
34
|
-
|
35
|
-
it "returns the first matching document" do
|
36
|
-
expect(result["name"]).to eq("Depeche Mode")
|
37
|
-
end
|
38
|
-
|
39
|
-
it "updates the document in the database" do
|
40
|
-
expect(depeche.reload.likes).to eq(1)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
context "when providing values that needs to be cast" do
|
45
|
-
|
46
|
-
let(:date_time) do
|
47
|
-
DateTime.new(1978, 1, 1)
|
48
|
-
end
|
49
|
-
|
50
|
-
let(:criteria) do
|
51
|
-
Band.where(name: "Depeche Mode")
|
52
|
-
end
|
53
|
-
|
54
|
-
let(:context) do
|
55
|
-
described_class.new(collection, criteria, { "$set" => { created: date_time }})
|
56
|
-
end
|
57
|
-
|
58
|
-
let!(:result) do
|
59
|
-
context.result
|
60
|
-
end
|
61
|
-
|
62
|
-
it "returns the first matching document" do
|
63
|
-
expect(result["name"]).to eq("Depeche Mode")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "updates the document in the database" do
|
67
|
-
expect(depeche.reload.created).to eq(date_time)
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context "when sorting" do
|
72
|
-
|
73
|
-
let(:criteria) do
|
74
|
-
Band.desc(:name)
|
75
|
-
end
|
76
|
-
|
77
|
-
let(:context) do
|
78
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }})
|
79
|
-
end
|
80
|
-
|
81
|
-
let!(:result) do
|
82
|
-
context.result
|
83
|
-
end
|
84
|
-
|
85
|
-
it "returns the first matching document" do
|
86
|
-
expect(result["name"]).to eq("Tool")
|
87
|
-
end
|
88
|
-
|
89
|
-
it "updates the document in the database" do
|
90
|
-
expect(tool.reload.likes).to eq(1)
|
91
|
-
end
|
92
|
-
end
|
93
|
-
|
94
|
-
context "when limiting fields" do
|
95
|
-
|
96
|
-
let(:criteria) do
|
97
|
-
Band.only(:_id)
|
98
|
-
end
|
99
|
-
|
100
|
-
let(:context) do
|
101
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }})
|
102
|
-
end
|
103
|
-
|
104
|
-
let!(:result) do
|
105
|
-
context.result
|
106
|
-
end
|
107
|
-
|
108
|
-
it "returns the first matching document" do
|
109
|
-
expect(result["_id"]).to eq(depeche.id)
|
110
|
-
end
|
111
|
-
|
112
|
-
it "limits the returned fields" do
|
113
|
-
expect(result["name"]).to be_nil
|
114
|
-
end
|
115
|
-
|
116
|
-
it "updates the document in the database" do
|
117
|
-
expect(depeche.reload.likes).to eq(1)
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context "when returning new" do
|
122
|
-
|
123
|
-
let(:criteria) do
|
124
|
-
Band.where(name: "Depeche Mode")
|
125
|
-
end
|
126
|
-
|
127
|
-
let(:context) do
|
128
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }}, new: true)
|
129
|
-
end
|
130
|
-
|
131
|
-
let!(:result) do
|
132
|
-
context.result
|
133
|
-
end
|
134
|
-
|
135
|
-
it "returns the first matching document" do
|
136
|
-
expect(result["name"]).to eq("Depeche Mode")
|
137
|
-
end
|
138
|
-
|
139
|
-
it "returns the updated document" do
|
140
|
-
expect(result["likes"]).to eq(1)
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context "when removing" do
|
145
|
-
|
146
|
-
let(:criteria) do
|
147
|
-
Band.where(name: "Depeche Mode")
|
148
|
-
end
|
149
|
-
|
150
|
-
let(:context) do
|
151
|
-
described_class.new(collection, criteria, {}, remove: true)
|
152
|
-
end
|
153
|
-
|
154
|
-
let!(:result) do
|
155
|
-
context.result
|
156
|
-
end
|
157
|
-
|
158
|
-
it "returns the first matching document" do
|
159
|
-
expect(result["name"]).to eq("Depeche Mode")
|
160
|
-
end
|
161
|
-
|
162
|
-
it "deletes the document from the database" do
|
163
|
-
expect {
|
164
|
-
depeche.reload
|
165
|
-
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
context "when upserting" do
|
170
|
-
|
171
|
-
let(:criteria) do
|
172
|
-
Band.where(name: "The Mars Volta")
|
173
|
-
end
|
174
|
-
|
175
|
-
let(:context) do
|
176
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }}, upsert: true)
|
177
|
-
end
|
178
|
-
|
179
|
-
let(:result) do
|
180
|
-
context.result
|
181
|
-
end
|
182
|
-
|
183
|
-
it "creates the document if it does not exist" do
|
184
|
-
expect {
|
185
|
-
result
|
186
|
-
}.to change{Band.where(name: "The Mars Volta").count}.from(0).to(1)
|
187
|
-
end
|
188
|
-
|
189
|
-
it "updates the document in the database if it does exist" do
|
190
|
-
the_mars_volta = Band.create(name: "The Mars Volta")
|
191
|
-
|
192
|
-
expect {
|
193
|
-
result
|
194
|
-
}.to_not change{Band.where(name: "The Mars Volta").count}
|
195
|
-
|
196
|
-
expect(the_mars_volta.reload.likes).to eq(1)
|
197
|
-
end
|
198
|
-
end
|
199
|
-
end
|
200
|
-
|
201
|
-
context "when the selector does not match" do
|
202
|
-
|
203
|
-
let(:criteria) do
|
204
|
-
Band.where(name: "Placebo")
|
205
|
-
end
|
206
|
-
|
207
|
-
let(:context) do
|
208
|
-
described_class.new(collection, criteria, { "$inc" => { likes: 1 }})
|
209
|
-
end
|
210
|
-
|
211
|
-
let(:result) do
|
212
|
-
context.result
|
213
|
-
end
|
214
|
-
|
215
|
-
it "returns nil" do
|
216
|
-
expect(result).to be_nil
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|