mongoid 5.0.0 → 5.0.1
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.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
@@ -84,7 +84,7 @@ module Mongoid
|
|
84
84
|
target
|
85
85
|
end
|
86
86
|
|
87
|
-
# Tell the next
|
87
|
+
# Tell the next persistence operation to store in a specific collection,
|
88
88
|
# database or client.
|
89
89
|
#
|
90
90
|
# @example Save the current document to a different collection.
|
@@ -31,7 +31,7 @@ module Mongoid
|
|
31
31
|
touches = touch_atomic_updates(field)
|
32
32
|
unless touches.empty?
|
33
33
|
selector = atomic_selector
|
34
|
-
_root.collection.find(selector).update_one(touches)
|
34
|
+
_root.collection.find(selector).update_one(positionally(selector, touches))
|
35
35
|
end
|
36
36
|
run_callbacks(:touch)
|
37
37
|
true
|
data/lib/mongoid/scopable.rb
CHANGED
@@ -115,7 +115,7 @@ module Mongoid
|
|
115
115
|
#
|
116
116
|
# @since 3.0.0
|
117
117
|
def queryable
|
118
|
-
Threaded.current_scope || Criteria.new(self)
|
118
|
+
Threaded.current_scope(self) || Criteria.new(self)
|
119
119
|
end
|
120
120
|
|
121
121
|
# Create a scope that can be accessed from the class level or chained to
|
@@ -222,11 +222,11 @@ module Mongoid
|
|
222
222
|
#
|
223
223
|
# @since 1.0.0
|
224
224
|
def with_scope(criteria)
|
225
|
-
Threaded.
|
225
|
+
Threaded.set_current_scope(criteria, self)
|
226
226
|
begin
|
227
227
|
yield criteria
|
228
228
|
ensure
|
229
|
-
Threaded.
|
229
|
+
Threaded.set_current_scope(nil, self)
|
230
230
|
end
|
231
231
|
end
|
232
232
|
|
@@ -311,11 +311,12 @@ module Mongoid
|
|
311
311
|
# @since 3.0.0
|
312
312
|
def define_scope_method(name)
|
313
313
|
singleton_class.class_eval do
|
314
|
-
define_method
|
314
|
+
define_method(name) do |*args|
|
315
315
|
scoping = _declared_scopes[name]
|
316
316
|
scope = instance_exec(*args, &scoping[:scope])
|
317
317
|
extension = scoping[:extension]
|
318
|
-
|
318
|
+
to_merge = scope || queryable
|
319
|
+
criteria = to_merge.empty_and_chainable? ? to_merge : with_default_scope.merge(to_merge)
|
319
320
|
criteria.extend(extension)
|
320
321
|
criteria
|
321
322
|
end
|
data/lib/mongoid/selectable.rb
CHANGED
@@ -18,7 +18,42 @@ module Mongoid
|
|
18
18
|
#
|
19
19
|
# @since 1.0.0
|
20
20
|
def atomic_selector
|
21
|
-
@atomic_selector ||=
|
21
|
+
@atomic_selector ||=
|
22
|
+
(embedded? ? embedded_atomic_selector : root_atomic_selector)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# Get the atomic selector for an embedded document.
|
28
|
+
#
|
29
|
+
# @api private
|
30
|
+
#
|
31
|
+
# @example Get the embedded atomic selector.
|
32
|
+
# document.embedded_atomic_selector
|
33
|
+
#
|
34
|
+
# @return [ Hash ] The embedded document selector.
|
35
|
+
#
|
36
|
+
# @since 4.0.0
|
37
|
+
def embedded_atomic_selector
|
38
|
+
if persisted? && _id_changed?
|
39
|
+
_parent.atomic_selector
|
40
|
+
else
|
41
|
+
_parent.atomic_selector.merge("#{atomic_path}._id" => _id)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# Get the atomic selector for a root document.
|
46
|
+
#
|
47
|
+
# @api private
|
48
|
+
#
|
49
|
+
# @example Get the root atomic selector.
|
50
|
+
# document.root_atomic_selector
|
51
|
+
#
|
52
|
+
# @return [ Hash ] The root document selector.
|
53
|
+
#
|
54
|
+
# @since 4.0.0
|
55
|
+
def root_atomic_selector
|
56
|
+
{ "_id" => _id }.merge!(shard_key_selector)
|
22
57
|
end
|
23
58
|
end
|
24
59
|
end
|
data/lib/mongoid/threaded.rb
CHANGED
@@ -197,13 +197,22 @@ module Mongoid
|
|
197
197
|
# Get the current Mongoid scope.
|
198
198
|
#
|
199
199
|
# @example Get the scope.
|
200
|
+
# Threaded.current_scope(klass)
|
200
201
|
# Threaded.current_scope
|
201
202
|
#
|
203
|
+
# @param [ Klass ] klass The class type of the scope.
|
204
|
+
#
|
202
205
|
# @return [ Criteria ] The scope.
|
203
206
|
#
|
204
207
|
# @since 5.0.0
|
205
|
-
def current_scope
|
206
|
-
Thread.current[CURRENT_SCOPE_KEY]
|
208
|
+
def current_scope(klass = nil)
|
209
|
+
if klass && Thread.current[CURRENT_SCOPE_KEY].respond_to?(:keys)
|
210
|
+
Thread.current[CURRENT_SCOPE_KEY][
|
211
|
+
Thread.current[CURRENT_SCOPE_KEY].keys.find { |k| k <= klass }
|
212
|
+
]
|
213
|
+
else
|
214
|
+
Thread.current[CURRENT_SCOPE_KEY]
|
215
|
+
end
|
207
216
|
end
|
208
217
|
|
209
218
|
# Set the current Mongoid scope.
|
@@ -220,6 +229,29 @@ module Mongoid
|
|
220
229
|
Thread.current[CURRENT_SCOPE_KEY] = scope
|
221
230
|
end
|
222
231
|
|
232
|
+
# Set the current Mongoid scope. Safe for multi-model scope chaining.
|
233
|
+
#
|
234
|
+
# @example Set the scope.
|
235
|
+
# Threaded.current_scope(scope, klass)
|
236
|
+
#
|
237
|
+
# @param [ Criteria ] scope The current scope.
|
238
|
+
# @param [ Class ] klass The current model class.
|
239
|
+
#
|
240
|
+
# @return [ Criteria ] The scope.
|
241
|
+
#
|
242
|
+
# @since 5.0.1
|
243
|
+
def set_current_scope(scope, klass)
|
244
|
+
if scope.nil?
|
245
|
+
if Thread.current[CURRENT_SCOPE_KEY]
|
246
|
+
Thread.current[CURRENT_SCOPE_KEY].delete(klass)
|
247
|
+
Thread.current[CURRENT_SCOPE_KEY] = nil if Thread.current[CURRENT_SCOPE_KEY].empty?
|
248
|
+
end
|
249
|
+
else
|
250
|
+
Thread.current[CURRENT_SCOPE_KEY] ||= {}
|
251
|
+
Thread.current[CURRENT_SCOPE_KEY][klass] = scope
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
223
255
|
# Is the document autosaved on the current thread?
|
224
256
|
#
|
225
257
|
# @example Is the document autosaved?
|
@@ -16,7 +16,12 @@ module Mongoid
|
|
16
16
|
#
|
17
17
|
# @since 3.1.4
|
18
18
|
def clear_timeless_option
|
19
|
-
self.
|
19
|
+
if self.persisted?
|
20
|
+
self.class.clear_timeless_option_on_update
|
21
|
+
else
|
22
|
+
self.class.clear_timeless_option
|
23
|
+
end
|
24
|
+
true
|
20
25
|
end
|
21
26
|
|
22
27
|
# Begin an execution that should skip timestamping.
|
@@ -67,11 +72,23 @@ module Mongoid
|
|
67
72
|
def clear_timeless_option
|
68
73
|
if counter = Timeless[name]
|
69
74
|
counter -= 1
|
70
|
-
|
75
|
+
set_timeless_counter(counter)
|
71
76
|
end
|
72
77
|
true
|
73
78
|
end
|
74
79
|
|
80
|
+
def clear_timeless_option_on_update
|
81
|
+
if counter = Timeless[name]
|
82
|
+
counter -= 1 if self < Mongoid::Timestamps::Created
|
83
|
+
counter -= 1 if self < Mongoid::Timestamps::Updated
|
84
|
+
set_timeless_counter(counter)
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def set_timeless_counter(counter)
|
89
|
+
Timeless[name] = (counter == 0) ? nil : counter
|
90
|
+
end
|
91
|
+
|
75
92
|
def timeless?
|
76
93
|
!!Timeless[name]
|
77
94
|
end
|
data/lib/mongoid/traversable.rb
CHANGED
data/lib/mongoid/version.rb
CHANGED
@@ -20,6 +20,8 @@ development:
|
|
20
20
|
# (default: primary)
|
21
21
|
# read:
|
22
22
|
# mode: :secondary_preferred
|
23
|
+
# tag_sets:
|
24
|
+
# - use: web
|
23
25
|
|
24
26
|
# The name of the user for authentication.
|
25
27
|
# user: 'user'
|
@@ -131,5 +133,5 @@ test:
|
|
131
133
|
- localhost:27017
|
132
134
|
options:
|
133
135
|
read:
|
134
|
-
mode: primary
|
136
|
+
mode: :primary
|
135
137
|
max_pool_size: 1
|
data/spec/app/models/account.rb
CHANGED
@@ -25,4 +25,12 @@ class Account
|
|
25
25
|
def overridden
|
26
26
|
self[:overridden] = "not recommended"
|
27
27
|
end
|
28
|
+
|
29
|
+
# MONGOID-3365
|
30
|
+
field :period_started_at, type: Time
|
31
|
+
has_many :consumption_periods, dependent: :destroy, validate: false
|
32
|
+
|
33
|
+
def current_consumption
|
34
|
+
consumption_periods.find_or_create_by(started_at: period_started_at)
|
35
|
+
end
|
28
36
|
end
|
data/spec/app/models/answer.rb
CHANGED
data/spec/app/models/article.rb
CHANGED
data/spec/app/models/author.rb
CHANGED
data/spec/app/models/book.rb
CHANGED
data/spec/app/models/note.rb
CHANGED
data/spec/app/models/page.rb
CHANGED
@@ -2,4 +2,15 @@ class Page
|
|
2
2
|
include Mongoid::Document
|
3
3
|
embedded_in :quiz
|
4
4
|
embeds_many :page_questions
|
5
|
+
|
6
|
+
embedded_in :book
|
7
|
+
embeds_many :notes
|
8
|
+
field :content, :type => String
|
9
|
+
|
10
|
+
after_initialize do
|
11
|
+
if self[:content]
|
12
|
+
self[:text] = self[:content]
|
13
|
+
self.remove_attribute(:content)
|
14
|
+
end
|
15
|
+
end
|
5
16
|
end
|
data/spec/config/mongoid.yml
CHANGED
@@ -18,7 +18,7 @@ describe Mongoid::Atomic::Paths do
|
|
18
18
|
Name.new
|
19
19
|
end
|
20
20
|
|
21
|
-
describe "
|
21
|
+
describe "#atomic_delete_modifier" do
|
22
22
|
|
23
23
|
before do
|
24
24
|
person.addresses << address
|
@@ -40,7 +40,7 @@ describe Mongoid::Atomic::Paths do
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
describe "
|
43
|
+
describe "#atomic_insert_modifier" do
|
44
44
|
|
45
45
|
before do
|
46
46
|
person.addresses << address
|
@@ -62,7 +62,7 @@ describe Mongoid::Atomic::Paths do
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
describe "
|
65
|
+
describe "#atomic_path" do
|
66
66
|
|
67
67
|
context "when the document is a parent" do
|
68
68
|
|
@@ -95,7 +95,7 @@ describe Mongoid::Atomic::Paths do
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
describe "
|
98
|
+
describe "#atomic_selector" do
|
99
99
|
|
100
100
|
context "when the document is a parent" do
|
101
101
|
|
@@ -111,7 +111,9 @@ describe Mongoid::Atomic::Paths do
|
|
111
111
|
end
|
112
112
|
|
113
113
|
it "returns the association with id.atomic_selector" do
|
114
|
-
expect(address.atomic_selector).to eq(
|
114
|
+
expect(address.atomic_selector).to eq(
|
115
|
+
{ "_id" => person.id, "addresses._id" => address.id }
|
116
|
+
)
|
115
117
|
end
|
116
118
|
end
|
117
119
|
|
@@ -122,13 +124,19 @@ describe Mongoid::Atomic::Paths do
|
|
122
124
|
person.addresses << address
|
123
125
|
end
|
124
126
|
|
125
|
-
it "returns the JSON notation to the document with
|
126
|
-
expect(location.atomic_selector).to eq(
|
127
|
+
it "returns the JSON notation to the document with ids" do
|
128
|
+
expect(location.atomic_selector).to eq(
|
129
|
+
{
|
130
|
+
"_id" => person.id,
|
131
|
+
"addresses._id" => address.id,
|
132
|
+
"addresses.locations._id" => location.id
|
133
|
+
}
|
134
|
+
)
|
127
135
|
end
|
128
136
|
end
|
129
137
|
end
|
130
138
|
|
131
|
-
describe "
|
139
|
+
describe "#atomic_position" do
|
132
140
|
|
133
141
|
context "when the document is a parent" do
|
134
142
|
|
@@ -194,7 +202,7 @@ describe Mongoid::Atomic::Paths do
|
|
194
202
|
end
|
195
203
|
end
|
196
204
|
|
197
|
-
describe "
|
205
|
+
describe "#atomic_path" do
|
198
206
|
|
199
207
|
context "when the document is a parent" do
|
200
208
|
|
@@ -255,7 +263,6 @@ describe Mongoid::Atomic::Paths do
|
|
255
263
|
it "returns the.atomic_path plus index" do
|
256
264
|
expect(location.atomic_path).to eq("addresses.0.locations")
|
257
265
|
end
|
258
|
-
|
259
266
|
end
|
260
267
|
end
|
261
268
|
end
|