mongoid 7.0.0.beta → 7.0.0
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 +5 -5
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/config/locales/en.yml +21 -0
- data/lib/mongoid.rb +1 -1
- data/lib/mongoid/association/embedded/batchable.rb +39 -13
- data/lib/mongoid/association/many.rb +4 -0
- data/lib/mongoid/association/referenced/has_many.rb +2 -0
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +38 -7
- data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -2
- data/lib/mongoid/association/referenced/syncable.rb +1 -1
- data/lib/mongoid/association/touchable.rb +1 -1
- data/lib/mongoid/atomic.rb +3 -3
- data/lib/mongoid/atomic/modifiers.rb +12 -8
- data/lib/mongoid/attributes.rb +20 -12
- data/lib/mongoid/attributes/dynamic.rb +2 -2
- data/lib/mongoid/changeable.rb +1 -1
- data/lib/mongoid/clients.rb +2 -0
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +1 -0
- data/lib/mongoid/composable.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +6 -3
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +6 -2
- data/lib/mongoid/contextual/memory.rb +25 -2
- data/lib/mongoid/contextual/mongo.rb +33 -14
- data/lib/mongoid/copyable.rb +2 -2
- data/lib/mongoid/criteria.rb +1 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +3 -1
- data/lib/mongoid/errors.rb +1 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/extensions/hash.rb +5 -2
- data/lib/mongoid/factory.rb +14 -5
- data/lib/mongoid/fields.rb +2 -2
- data/lib/mongoid/indexable.rb +4 -4
- data/lib/mongoid/matchable/and.rb +1 -1
- data/lib/mongoid/matchable/elem_match.rb +9 -3
- data/lib/mongoid/persistable.rb +2 -2
- data/lib/mongoid/persistable/creatable.rb +4 -2
- data/lib/mongoid/persistable/deletable.rb +4 -2
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistence_context.rb +5 -4
- data/lib/mongoid/query_cache.rb +5 -3
- data/lib/mongoid/reloadable.rb +1 -1
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/shardable.rb +1 -1
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +38 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -0
- data/spec/app/models/band.rb +1 -0
- data/spec/app/models/shipment_address.rb +1 -0
- data/spec/mongoid/association/macros_spec.rb +20 -0
- data/spec/mongoid/association/referenced/has_many/eager_spec.rb +15 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +229 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +17 -17
- data/spec/mongoid/atomic_spec.rb +17 -17
- data/spec/mongoid/attributes_spec.rb +38 -2
- data/spec/mongoid/clients/sessions_spec.rb +325 -0
- data/spec/mongoid/contextual/memory_spec.rb +19 -0
- data/spec/mongoid/contextual/mongo_spec.rb +133 -0
- data/spec/mongoid/copyable_spec.rb +34 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +43 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +32 -3
- data/spec/mongoid/extensions/hash_spec.rb +18 -1
- data/spec/mongoid/factory_spec.rb +11 -0
- data/spec/mongoid/interceptable_spec.rb +3 -1
- data/spec/mongoid/matchable/elem_match_spec.rb +20 -0
- data/spec/mongoid/persistable/deletable_spec.rb +19 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +19 -0
- data/spec/mongoid/persistable/savable_spec.rb +2 -2
- data/spec/mongoid/persistable/updatable_spec.rb +2 -2
- data/spec/mongoid/persistable_spec.rb +31 -16
- data/spec/mongoid/persistence_context_spec.rb +14 -0
- data/spec/mongoid/positional_spec.rb +10 -10
- data/spec/mongoid/query_cache_spec.rb +2 -16
- data/spec/mongoid/shardable_spec.rb +32 -12
- data/spec/spec_helper.rb +74 -0
- metadata +456 -446
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8d7943ffc77e9a6990cb063c1301476cd1d5b10cd8543f0e9861e96228ff8027
|
4
|
+
data.tar.gz: bc71866e339c29688dae94bdd8b4590b198ab25b503bc321802d6acea4af5c25
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 51e00c706c33a552c148b768bf851042a2f5c46aecacd3aa6bed5105c8c9b002bf84f317b1d5d65ee209e153537af5fb7360560758aef34ca4cbc39ffa11b489
|
7
|
+
data.tar.gz: 81a21a9ee3e6aa381bb495eb098b7faba65f2fa32c304460ecb481356ab505bb1189c4850cf218680d93c269cb656360727d3ed3fd967de5525ff92bf510425d
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/config/locales/en.yml
CHANGED
@@ -216,6 +216,20 @@ en:
|
|
216
216
|
\_\_\_\_include Mongoid::Document\n
|
217
217
|
\_\_\_\_scope :inactive, ->{ where(active: false) }\n
|
218
218
|
\_\_end\n\n"
|
219
|
+
invalid_session_use:
|
220
|
+
message: "A session was attempted to be used with a model whose client cannot use
|
221
|
+
that session."
|
222
|
+
summary: "Sessions are started via driver clients (Model#mongo_client) and, in most cases, driver
|
223
|
+
clients are shared across models. When different models have their own clients, a session cannot
|
224
|
+
be obtained via one model and used for operations on another model."
|
225
|
+
resolution: "Only execute operations on the model class or instances of the model through which
|
226
|
+
the session was created. Otherwise, ensure that all models on which operations are executed
|
227
|
+
in the session block share the same driver client. For example, a model may have a different
|
228
|
+
client specified in its 'store_in' options.\n\n"
|
229
|
+
invalid_session_nesting:
|
230
|
+
message: "A session was started while another session was being used."
|
231
|
+
summary: "Sessions cannot be nested. Only one session can be used in a thread at once."
|
232
|
+
resolution: "Only use one session at a time; sessions cannot be nested."
|
219
233
|
invalid_storage_options:
|
220
234
|
message: "Invalid options passed to %{klass}.store_in: %{options}."
|
221
235
|
summary: "The :store_in macro takes only a hash of parameters with
|
@@ -462,6 +476,13 @@ en:
|
|
462
476
|
with the already defined method %{model_name}, or set the
|
463
477
|
configuration option Mongoid.scope_overwrite_exception to false,
|
464
478
|
which is its default. In this case a warning will be logged."
|
479
|
+
sessions_not_supported:
|
480
|
+
message: "Sessions are not supported by the connected server(s)."
|
481
|
+
summary: "A session was attempted to be used with a MongoDB server version
|
482
|
+
that doesn't support sessions. Sessions are supported in MongoDB
|
483
|
+
server versions 3.6 and higher."
|
484
|
+
resolution: "Verify that all servers in your deployment are at least
|
485
|
+
version 3.6 or don't attempt to use sessions with older server versions."
|
465
486
|
taken:
|
466
487
|
"is already taken"
|
467
488
|
too_many_nested_attribute_records:
|
data/lib/mongoid.rb
CHANGED
@@ -8,7 +8,7 @@ module Mongoid
|
|
8
8
|
module Batchable
|
9
9
|
include Positional
|
10
10
|
|
11
|
-
# Insert new documents as a batch push ($
|
11
|
+
# Insert new documents as a batch push ($push with $each). This ensures that
|
12
12
|
# all callbacks are run at the appropriate time and only 1 request is
|
13
13
|
# made to the database.
|
14
14
|
#
|
@@ -21,7 +21,7 @@ module Mongoid
|
|
21
21
|
#
|
22
22
|
# @since 3.0.0
|
23
23
|
def batch_insert(docs)
|
24
|
-
|
24
|
+
execute_batch_push(docs)
|
25
25
|
end
|
26
26
|
|
27
27
|
# Clear all of the docs out of the relation in a single swipe.
|
@@ -38,7 +38,8 @@ module Mongoid
|
|
38
38
|
pre_process_batch_remove(docs, :delete)
|
39
39
|
unless docs.empty?
|
40
40
|
collection.find(selector).update_one(
|
41
|
-
positionally(selector, "$unset" => { path => true })
|
41
|
+
positionally(selector, "$unset" => { path => true }),
|
42
|
+
session: session
|
42
43
|
)
|
43
44
|
post_process_batch_remove(docs, :delete)
|
44
45
|
end
|
@@ -58,7 +59,8 @@ module Mongoid
|
|
58
59
|
removals = pre_process_batch_remove(docs, method)
|
59
60
|
if !docs.empty?
|
60
61
|
collection.find(selector).update_one(
|
61
|
-
positionally(selector, "$pullAll" => { path => removals })
|
62
|
+
positionally(selector, "$pullAll" => { path => removals }),
|
63
|
+
session: session
|
62
64
|
)
|
63
65
|
post_process_batch_remove(docs, method)
|
64
66
|
end
|
@@ -89,7 +91,7 @@ module Mongoid
|
|
89
91
|
_base.delayed_atomic_sets.clear unless _assigning?
|
90
92
|
docs = normalize_docs(docs).compact
|
91
93
|
_target.clear and _unscoped.clear
|
92
|
-
inserts =
|
94
|
+
inserts = execute_batch_set(docs)
|
93
95
|
add_atomic_sets(inserts)
|
94
96
|
end
|
95
97
|
end
|
@@ -116,32 +118,56 @@ module Mongoid
|
|
116
118
|
end
|
117
119
|
end
|
118
120
|
|
119
|
-
# Perform a batch persist of the provided documents with
|
120
|
-
# operation.
|
121
|
+
# Perform a batch persist of the provided documents with a $set.
|
121
122
|
#
|
122
123
|
# @api private
|
123
124
|
#
|
124
|
-
# @example Perform a batch
|
125
|
-
# batchable.
|
125
|
+
# @example Perform a batch $set.
|
126
|
+
# batchable.execute_batch_set(docs)
|
126
127
|
#
|
127
128
|
# @param [ Array<Document> ] docs The docs to persist.
|
128
|
-
# @param [ String ] operation The atomic operation.
|
129
129
|
#
|
130
130
|
# @return [ Array<Hash> ] The inserts.
|
131
131
|
#
|
132
|
-
# @since
|
133
|
-
def
|
132
|
+
# @since 7.0.0
|
133
|
+
def execute_batch_set(docs)
|
134
134
|
self.inserts_valid = true
|
135
135
|
inserts = pre_process_batch_insert(docs)
|
136
136
|
if insertable?
|
137
137
|
collection.find(selector).update_one(
|
138
|
-
positionally(selector,
|
138
|
+
positionally(selector, '$set' => { path => inserts }),
|
139
|
+
session: session
|
139
140
|
)
|
140
141
|
post_process_batch_insert(docs)
|
141
142
|
end
|
142
143
|
inserts
|
143
144
|
end
|
144
145
|
|
146
|
+
# Perform a batch persist of the provided documents with $push and $each.
|
147
|
+
#
|
148
|
+
# @api private
|
149
|
+
#
|
150
|
+
# @example Perform a batch push.
|
151
|
+
# batchable.execute_batch_push(docs)
|
152
|
+
#
|
153
|
+
# @param [ Array<Document> ] docs The docs to persist.
|
154
|
+
#
|
155
|
+
# @return [ Array<Hash> ] The inserts.
|
156
|
+
#
|
157
|
+
# @since 7.0.0
|
158
|
+
def execute_batch_push(docs)
|
159
|
+
self.inserts_valid = true
|
160
|
+
pushes = pre_process_batch_insert(docs)
|
161
|
+
if insertable?
|
162
|
+
collection.find(selector).update_one(
|
163
|
+
positionally(selector, '$push' => { path => { '$each' => pushes } }),
|
164
|
+
session: session
|
165
|
+
)
|
166
|
+
post_process_batch_insert(docs)
|
167
|
+
end
|
168
|
+
pushes
|
169
|
+
end
|
170
|
+
|
145
171
|
# Are we in a state to be able to batch insert?
|
146
172
|
#
|
147
173
|
# @api private
|
@@ -179,12 +179,14 @@ module Mongoid
|
|
179
179
|
if _loaded?
|
180
180
|
_loaded.each_pair do |id, doc|
|
181
181
|
document = _added.delete(doc._id) || doc
|
182
|
+
set_base(document)
|
182
183
|
yield(document)
|
183
184
|
end
|
184
185
|
else
|
185
186
|
unloaded_documents.each do |doc|
|
186
187
|
document = _added.delete(doc._id) || _loaded.delete(doc._id) || doc
|
187
188
|
_loaded[document._id] = document
|
189
|
+
set_base(document)
|
188
190
|
yield(document)
|
189
191
|
end
|
190
192
|
end
|
@@ -217,12 +219,22 @@ module Mongoid
|
|
217
219
|
# @example Get the first document.
|
218
220
|
# enumerable.first
|
219
221
|
#
|
222
|
+
# @note Automatically adding a sort on _id when no other sort is
|
223
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
224
|
+
# If you experience unexpected poor performance when using #first or #last,
|
225
|
+
# use the option { id_sort: :none }.
|
226
|
+
# Be aware that #first/#last won't guarantee order in this case.
|
227
|
+
#
|
228
|
+
# @param [ Hash ] opts The options for the query returning the first document.
|
229
|
+
#
|
230
|
+
# @option opts [ :none ] :id_sort Don't apply a sort on _id.
|
231
|
+
#
|
220
232
|
# @return [ Document ] The first document found.
|
221
233
|
#
|
222
234
|
# @since 2.1.0
|
223
|
-
def first
|
235
|
+
def first(opts = {})
|
224
236
|
_loaded.try(:values).try(:first) ||
|
225
|
-
_added[(ul = _unloaded.try(:first)).try(:id)] ||
|
237
|
+
_added[(ul = _unloaded.try(:first, opts)).try(:id)] ||
|
226
238
|
ul ||
|
227
239
|
_added.values.try(:first)
|
228
240
|
end
|
@@ -238,7 +250,9 @@ module Mongoid
|
|
238
250
|
# @param [ Criteria, Array<Document> ] target The wrapped object.
|
239
251
|
#
|
240
252
|
# @since 2.1.0
|
241
|
-
def initialize(target)
|
253
|
+
def initialize(target, base = nil, association = nil)
|
254
|
+
@_base = base
|
255
|
+
@_association = association
|
242
256
|
if target.is_a?(Criteria)
|
243
257
|
@_added, @executed, @_loaded, @_unloaded = {}, false, {}, target
|
244
258
|
else
|
@@ -291,8 +305,9 @@ module Mongoid
|
|
291
305
|
# @since 2.1.0
|
292
306
|
def in_memory
|
293
307
|
docs = (_loaded.values + _added.values)
|
294
|
-
docs.each
|
295
|
-
|
308
|
+
docs.each do |doc|
|
309
|
+
yield(doc) if block_given?
|
310
|
+
end
|
296
311
|
end
|
297
312
|
|
298
313
|
# Get the last document in the enumerable. Will check the new
|
@@ -301,13 +316,23 @@ module Mongoid
|
|
301
316
|
# @example Get the last document.
|
302
317
|
# enumerable.last
|
303
318
|
#
|
319
|
+
# @note Automatically adding a sort on _id when no other sort is
|
320
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
321
|
+
# If you experience unexpected poor performance when using #first or #last,
|
322
|
+
# use the option { id_sort: :none }.
|
323
|
+
# Be aware that #first/#last won't guarantee order in this case.
|
324
|
+
#
|
325
|
+
# @param [ Hash ] opts The options for the query returning the first document.
|
326
|
+
#
|
327
|
+
# @option opts [ :none ] :id_sort Don't apply a sort on _id.
|
328
|
+
#
|
304
329
|
# @return [ Document ] The last document found.
|
305
330
|
#
|
306
331
|
# @since 2.1.0
|
307
|
-
def last
|
332
|
+
def last(opts = {})
|
308
333
|
_added.values.try(:last) ||
|
309
334
|
_loaded.try(:values).try(:last) ||
|
310
|
-
_added[(ul = _unloaded.try(:last)).try(:id)] ||
|
335
|
+
_added[(ul = _unloaded.try(:last, opts)).try(:id)] ||
|
311
336
|
ul
|
312
337
|
end
|
313
338
|
|
@@ -464,6 +489,12 @@ module Mongoid
|
|
464
489
|
|
465
490
|
private
|
466
491
|
|
492
|
+
def set_base(document)
|
493
|
+
if @_association.is_a?(Referenced::HasMany)
|
494
|
+
document.set_relation(@_association.inverse, @_base) if @_association
|
495
|
+
end
|
496
|
+
end
|
497
|
+
|
467
498
|
def method_missing(name, *args, &block)
|
468
499
|
entries.send(name, *args, &block)
|
469
500
|
end
|
@@ -210,7 +210,8 @@ module Mongoid
|
|
210
210
|
#
|
211
211
|
# @since 2.0.0.beta.1
|
212
212
|
def initialize(base, target, association)
|
213
|
-
|
213
|
+
enum = HasMany::Targets::Enumerable.new(target, base, association)
|
214
|
+
init(base, enum, association) do
|
214
215
|
raise_mixed if klass.embedded? && !klass.cyclic?
|
215
216
|
end
|
216
217
|
end
|
@@ -455,7 +456,7 @@ module Mongoid
|
|
455
456
|
# @since 3.0.0
|
456
457
|
def persist_delayed(docs, inserts)
|
457
458
|
unless docs.empty?
|
458
|
-
collection.insert_many(inserts)
|
459
|
+
collection.insert_many(inserts, session: session)
|
459
460
|
docs.each do |doc|
|
460
461
|
doc.new_record = false
|
461
462
|
doc.run_after_callbacks(:create, :save)
|
@@ -81,7 +81,7 @@ module Mongoid
|
|
81
81
|
adds, subs = new - (old || []), (old || []) - new
|
82
82
|
|
83
83
|
# If we are autosaving we don't want a duplicate to get added - the
|
84
|
-
# $addToSet would run previously and then the $
|
84
|
+
# $addToSet would run previously and then the $push and $each from the
|
85
85
|
# inverse on the autosave would cause this. We delete each id from
|
86
86
|
# what's in memory in case a mix of id addition and object addition
|
87
87
|
# had occurred.
|
@@ -32,7 +32,7 @@ module Mongoid
|
|
32
32
|
touches = touch_atomic_updates(field)
|
33
33
|
unless touches["$set"].blank?
|
34
34
|
selector = atomic_selector
|
35
|
-
_root.collection.find(selector).update_one(positionally(selector, touches))
|
35
|
+
_root.collection.find(selector).update_one(positionally(selector, touches), session: session)
|
36
36
|
end
|
37
37
|
run_callbacks(:touch)
|
38
38
|
true
|
data/lib/mongoid/atomic.rb
CHANGED
@@ -110,10 +110,10 @@ module Mongoid
|
|
110
110
|
# performed in a single operation. Conflicting modifications are
|
111
111
|
# detected by the 'haveConflictingMod' function in MongoDB.
|
112
112
|
# Examination of the code suggests that two modifications (a $set
|
113
|
-
# and a $
|
113
|
+
# and a $push with $each, for example) conflict if:
|
114
114
|
# (1) the key paths being modified are equal.
|
115
115
|
# (2) one key path is a prefix of the other.
|
116
|
-
# So a $set of 'addresses.0.street' will conflict with a $
|
116
|
+
# So a $set of 'addresses.0.street' will conflict with a $push and $each
|
117
117
|
# to 'addresses', and we will need to split our update into two
|
118
118
|
# pieces. We do not, however, attempt to match MongoDB's logic
|
119
119
|
# exactly. Instead, we assume that two updates conflict if the
|
@@ -218,7 +218,7 @@ module Mongoid
|
|
218
218
|
# @example Get the pushes.
|
219
219
|
# person.atomic_pushes
|
220
220
|
#
|
221
|
-
# @return [ Hash ] The $
|
221
|
+
# @return [ Hash ] The $push and $each operations.
|
222
222
|
#
|
223
223
|
# @since 2.1.0
|
224
224
|
def atomic_pushes
|
@@ -68,7 +68,7 @@ module Mongoid
|
|
68
68
|
modifications.each_pair do |field, value|
|
69
69
|
push_fields[field] = field
|
70
70
|
mods = push_conflict?(field) ? conflicting_pushes : pushes
|
71
|
-
add_operation(mods, field, Array.wrap(value))
|
71
|
+
add_operation(mods, field, { '$each' => Array.wrap(value) })
|
72
72
|
end
|
73
73
|
end
|
74
74
|
|
@@ -118,8 +118,12 @@ module Mongoid
|
|
118
118
|
# @since 2.2.0
|
119
119
|
def add_operation(mods, field, value)
|
120
120
|
if mods.has_key?(field)
|
121
|
-
|
122
|
-
|
121
|
+
if mods[field].is_a?(Array)
|
122
|
+
value.each do |val|
|
123
|
+
mods[field].push(val)
|
124
|
+
end
|
125
|
+
elsif mods[field]['$each']
|
126
|
+
mods[field]['$each'].concat(value['$each'])
|
123
127
|
end
|
124
128
|
else
|
125
129
|
mods[field] = value
|
@@ -190,7 +194,7 @@ module Mongoid
|
|
190
194
|
#
|
191
195
|
# @since 2.2.0
|
192
196
|
def conflicting_pushes
|
193
|
-
conflicts["$
|
197
|
+
conflicts["$push"] ||= {}
|
194
198
|
end
|
195
199
|
|
196
200
|
# Get the conflicting set modifications.
|
@@ -277,16 +281,16 @@ module Mongoid
|
|
277
281
|
self["$pull"] ||= {}
|
278
282
|
end
|
279
283
|
|
280
|
-
# Get the $
|
284
|
+
# Get the $push/$each operations or initialize a new one.
|
281
285
|
#
|
282
|
-
# @example Get the $
|
286
|
+
# @example Get the $push/$each operations.
|
283
287
|
# modifiers.pushes
|
284
288
|
#
|
285
|
-
# @return [ Hash ] The $
|
289
|
+
# @return [ Hash ] The $push/$each operations.
|
286
290
|
#
|
287
291
|
# @since 2.1.0
|
288
292
|
def pushes
|
289
|
-
self["$
|
293
|
+
self["$push"] ||= {}
|
290
294
|
end
|
291
295
|
|
292
296
|
# Get the $set operations or intialize a new one.
|
data/lib/mongoid/attributes.rb
CHANGED
@@ -29,7 +29,7 @@ module Mongoid
|
|
29
29
|
#
|
30
30
|
# @since 1.0.0
|
31
31
|
def attribute_present?(name)
|
32
|
-
attribute =
|
32
|
+
attribute = read_raw_attribute(name)
|
33
33
|
!attribute.blank? || attribute == false
|
34
34
|
rescue ActiveModel::MissingAttributeError
|
35
35
|
false
|
@@ -92,21 +92,15 @@ module Mongoid
|
|
92
92
|
#
|
93
93
|
# @since 1.0.0
|
94
94
|
def read_attribute(name)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
end
|
99
|
-
if hash_dot_syntax?(normalized)
|
100
|
-
attributes.__nested__(normalized)
|
101
|
-
else
|
102
|
-
attributes[normalized]
|
103
|
-
end
|
95
|
+
field = fields[name.to_s]
|
96
|
+
raw = read_raw_attribute(name)
|
97
|
+
field ? field.demongoize(raw) : raw
|
104
98
|
end
|
105
99
|
alias :[] :read_attribute
|
106
100
|
|
107
101
|
# Read a value from the attributes before type cast. If the value has not
|
108
102
|
# yet been assigned then this will return the attribute's existing value
|
109
|
-
# using
|
103
|
+
# using read_raw_attribute.
|
110
104
|
#
|
111
105
|
# @example Read an attribute before type cast.
|
112
106
|
# person.read_attribute_before_type_cast(:price)
|
@@ -122,7 +116,7 @@ module Mongoid
|
|
122
116
|
if attributes_before_type_cast.key?(attr)
|
123
117
|
attributes_before_type_cast[attr]
|
124
118
|
else
|
125
|
-
|
119
|
+
read_raw_attribute(attr)
|
126
120
|
end
|
127
121
|
end
|
128
122
|
|
@@ -293,6 +287,20 @@ module Mongoid
|
|
293
287
|
fields.key?(key) ? fields[key].mongoize(value) : value.mongoize
|
294
288
|
end
|
295
289
|
|
290
|
+
private
|
291
|
+
|
292
|
+
def read_raw_attribute(name)
|
293
|
+
normalized = database_field_name(name.to_s)
|
294
|
+
if attribute_missing?(normalized)
|
295
|
+
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'."
|
296
|
+
end
|
297
|
+
if hash_dot_syntax?(normalized)
|
298
|
+
attributes.__nested__(normalized)
|
299
|
+
else
|
300
|
+
attributes[normalized]
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
296
304
|
module ClassMethods
|
297
305
|
|
298
306
|
# Alias the provided name to the original field. This will provide an
|