mongoid 8.0.5 → 8.1.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +3 -3
- data/README.md +3 -3
- data/Rakefile +0 -25
- data/lib/config/locales/en.yml +46 -14
- data/lib/mongoid/association/accessors.rb +2 -2
- data/lib/mongoid/association/builders.rb +1 -1
- data/lib/mongoid/association/embedded/batchable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
- data/lib/mongoid/association/nested/one.rb +40 -2
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/atomic.rb +0 -7
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/attributes/nested.rb +2 -2
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +1 -1
- data/lib/mongoid/attributes.rb +8 -2
- data/lib/mongoid/changeable.rb +107 -5
- data/lib/mongoid/clients/storage_options.rb +2 -5
- data/lib/mongoid/clients/validators/storage.rb +1 -13
- data/lib/mongoid/collection_configurable.rb +58 -0
- data/lib/mongoid/composable.rb +2 -0
- data/lib/mongoid/config/defaults.rb +60 -0
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +101 -0
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +233 -33
- data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
- data/lib/mongoid/contextual/mongo.rb +373 -113
- data/lib/mongoid/contextual/none.rb +162 -7
- data/lib/mongoid/contextual.rb +12 -0
- data/lib/mongoid/criteria/findable.rb +2 -2
- data/lib/mongoid/criteria/includable.rb +4 -3
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
- data/lib/mongoid/criteria/queryable/optional.rb +8 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
- data/lib/mongoid/criteria.rb +6 -5
- data/lib/mongoid/deprecable.rb +1 -1
- data/lib/mongoid/errors/create_collection_failure.rb +33 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
- data/lib/mongoid/errors/immutable_attribute.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
- data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
- data/lib/mongoid/errors.rb +4 -1
- data/lib/mongoid/extensions/object.rb +2 -2
- data/lib/mongoid/extensions/time.rb +2 -0
- data/lib/mongoid/fields/localized.rb +10 -0
- data/lib/mongoid/fields/standard.rb +10 -0
- data/lib/mongoid/fields.rb +69 -13
- data/lib/mongoid/findable.rb +27 -3
- data/lib/mongoid/interceptable.rb +7 -6
- data/lib/mongoid/matcher/eq_impl.rb +1 -1
- data/lib/mongoid/matcher/type.rb +1 -1
- data/lib/mongoid/persistable/creatable.rb +1 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +13 -1
- data/lib/mongoid/persistable/unsettable.rb +2 -2
- data/lib/mongoid/persistable/updatable.rb +51 -1
- data/lib/mongoid/persistable/upsertable.rb +20 -1
- data/lib/mongoid/persistable.rb +3 -0
- data/lib/mongoid/query_cache.rb +5 -1
- data/lib/mongoid/railties/database.rake +7 -2
- data/lib/mongoid/reloadable.rb +5 -3
- data/lib/mongoid/stateful.rb +22 -1
- data/lib/mongoid/tasks/database.rake +12 -0
- data/lib/mongoid/tasks/database.rb +20 -0
- data/lib/mongoid/utils.rb +22 -0
- data/lib/mongoid/validatable/macros.rb +5 -5
- data/lib/mongoid/validatable.rb +4 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +17 -1
- data/lib/mongoid.rb +16 -3
- data/spec/integration/app_spec.rb +2 -2
- data/spec/integration/callbacks_models.rb +37 -0
- data/spec/integration/callbacks_spec.rb +134 -0
- data/spec/integration/discriminator_key_spec.rb +4 -5
- data/spec/integration/i18n_fallbacks_spec.rb +3 -2
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +5 -27
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
- data/spec/mongoid/association/syncable_spec.rb +1 -1
- data/spec/mongoid/attributes_spec.rb +3 -6
- data/spec/mongoid/changeable_spec.rb +299 -24
- data/spec/mongoid/clients_spec.rb +122 -13
- data/spec/mongoid/collection_configurable_spec.rb +158 -0
- data/spec/mongoid/config/defaults_spec.rb +160 -0
- data/spec/mongoid/config_spec.rb +154 -18
- data/spec/mongoid/contextual/memory_spec.rb +332 -76
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
- data/spec/mongoid/contextual/mongo_spec.rb +995 -36
- data/spec/mongoid/contextual/none_spec.rb +49 -2
- data/spec/mongoid/copyable_spec.rb +3 -11
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
- data/spec/mongoid/criteria_projection_spec.rb +1 -4
- data/spec/mongoid/criteria_spec.rb +5 -9
- data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
- data/spec/mongoid/extensions/time_spec.rb +8 -43
- data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
- data/spec/mongoid/fields/localized_spec.rb +46 -28
- data/spec/mongoid/fields_spec.rb +136 -34
- data/spec/mongoid/findable_spec.rb +391 -34
- data/spec/mongoid/indexable_spec.rb +16 -10
- data/spec/mongoid/interceptable_spec.rb +15 -3
- data/spec/mongoid/persistable/deletable_spec.rb +26 -6
- data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
- data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
- data/spec/mongoid/persistable/logical_spec.rb +37 -0
- data/spec/mongoid/persistable/poppable_spec.rb +36 -0
- data/spec/mongoid/persistable/pullable_spec.rb +72 -0
- data/spec/mongoid/persistable/pushable_spec.rb +72 -0
- data/spec/mongoid/persistable/renamable_spec.rb +36 -0
- data/spec/mongoid/persistable/savable_spec.rb +96 -0
- data/spec/mongoid/persistable/settable_spec.rb +37 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
- data/spec/mongoid/persistable/updatable_spec.rb +20 -28
- data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
- data/spec/mongoid/persistence_context_spec.rb +7 -57
- data/spec/mongoid/query_cache_spec.rb +56 -61
- data/spec/mongoid/reloadable_spec.rb +24 -28
- data/spec/mongoid/scopable_spec.rb +70 -0
- data/spec/mongoid/serializable_spec.rb +9 -30
- data/spec/mongoid/stateful_spec.rb +122 -8
- data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
- data/spec/mongoid/tasks/database_spec.rb +127 -0
- data/spec/mongoid/timestamps_spec.rb +9 -11
- data/spec/mongoid/touchable_spec.rb +277 -5
- data/spec/mongoid/touchable_spec_models.rb +3 -1
- data/spec/mongoid/traversable_spec.rb +9 -24
- data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
- data/spec/mongoid_spec.rb +36 -10
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/spec_helper.rb +5 -0
- data/spec/support/immutable_ids.rb +118 -0
- data/spec/support/macros.rb +47 -15
- data/spec/support/models/artist.rb +0 -1
- data/spec/support/models/band.rb +1 -0
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/building.rb +2 -0
- data/spec/support/models/cover.rb +10 -0
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +686 -650
- metadata.gz.sig +0 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "mongoid/contextual/mongo/documents_loader"
|
3
4
|
require "mongoid/contextual/atomic"
|
4
5
|
require "mongoid/contextual/aggregable/mongo"
|
5
6
|
require "mongoid/contextual/command"
|
@@ -37,6 +38,18 @@ module Mongoid
|
|
37
38
|
# @attribute [r] view The Mongo collection view.
|
38
39
|
attr_reader :view
|
39
40
|
|
41
|
+
# Run an explain on the criteria.
|
42
|
+
#
|
43
|
+
# @example Explain the criteria.
|
44
|
+
# Band.where(name: "Depeche Mode").explain
|
45
|
+
#
|
46
|
+
# @param [ Hash ] options customizable options (See Mongo::Collection::View::Explainable)
|
47
|
+
#
|
48
|
+
# @return [ Hash ] The explain result.
|
49
|
+
def_delegator :view, :explain
|
50
|
+
|
51
|
+
attr_reader :documents_loader
|
52
|
+
|
40
53
|
# Get the number of documents matching the query.
|
41
54
|
#
|
42
55
|
# @example Get the number of matching documents.
|
@@ -154,22 +167,28 @@ module Mongoid
|
|
154
167
|
# @example Do any documents exist for the context.
|
155
168
|
# context.exists?
|
156
169
|
#
|
170
|
+
# @example Do any documents exist for given _id.
|
171
|
+
# context.exists?(BSON::ObjectId(...))
|
172
|
+
#
|
173
|
+
# @example Do any documents exist for given conditions.
|
174
|
+
# context.exists?(name: "...")
|
175
|
+
#
|
157
176
|
# @note We don't use count here since Mongo does not use counted
|
158
177
|
# b-tree indexes.
|
159
178
|
#
|
160
|
-
# @
|
161
|
-
|
162
|
-
!!(view.projection(_id: 1).limit(1).first)
|
163
|
-
end
|
164
|
-
|
165
|
-
# Run an explain on the criteria.
|
166
|
-
#
|
167
|
-
# @example Explain the criteria.
|
168
|
-
# Band.where(name: "Depeche Mode").explain
|
179
|
+
# @param [ Hash | Object | false ] id_or_conditions an _id to
|
180
|
+
# search for, a hash of conditions, nil or false.
|
169
181
|
#
|
170
|
-
# @return [
|
171
|
-
|
172
|
-
|
182
|
+
# @return [ true | false ] If the count is more than zero.
|
183
|
+
# Always false if passed nil or false.
|
184
|
+
def exists?(id_or_conditions = :none)
|
185
|
+
return false if self.view.limit == 0
|
186
|
+
case id_or_conditions
|
187
|
+
when :none then !!(view.projection(_id: 1).limit(1).first)
|
188
|
+
when nil, false then false
|
189
|
+
when Hash then Mongo.new(criteria.where(id_or_conditions)).exists?
|
190
|
+
else Mongo.new(criteria.where(_id: id_or_conditions)).exists?
|
191
|
+
end
|
173
192
|
end
|
174
193
|
|
175
194
|
# Execute the find and modify command, used for MongoDB's
|
@@ -225,28 +244,6 @@ module Mongoid
|
|
225
244
|
end
|
226
245
|
end
|
227
246
|
|
228
|
-
# Get the first document in the database for the criteria's selector.
|
229
|
-
#
|
230
|
-
# @example Get the first document.
|
231
|
-
# context.first
|
232
|
-
#
|
233
|
-
# @note Automatically adding a sort on _id when no other sort is
|
234
|
-
# defined on the criteria has the potential to cause bad performance issues.
|
235
|
-
# If you experience unexpected poor performance when using #first or #last
|
236
|
-
# and have no sort defined on the criteria, use #take instead.
|
237
|
-
# Be aware that #take won't guarantee order.
|
238
|
-
#
|
239
|
-
# @param [ Integer ] limit The number of documents to return.
|
240
|
-
#
|
241
|
-
# @return [ Document ] The first document.
|
242
|
-
def first(limit = nil)
|
243
|
-
sort = view.sort || { _id: 1 }
|
244
|
-
if raw_docs = view.sort(sort).limit(limit || 1).to_a
|
245
|
-
process_raw_docs(raw_docs, limit)
|
246
|
-
end
|
247
|
-
end
|
248
|
-
alias :one :first
|
249
|
-
|
250
247
|
# Return the first result without applying sort
|
251
248
|
#
|
252
249
|
# @api private
|
@@ -297,25 +294,6 @@ module Mongoid
|
|
297
294
|
|
298
295
|
def_delegator :@klass, :database_field_name
|
299
296
|
|
300
|
-
# Get the last document in the database for the criteria's selector.
|
301
|
-
#
|
302
|
-
# @example Get the last document.
|
303
|
-
# context.last
|
304
|
-
#
|
305
|
-
# @note Automatically adding a sort on _id when no other sort is
|
306
|
-
# defined on the criteria has the potential to cause bad performance issues.
|
307
|
-
# If you experience unexpected poor performance when using #first or #last
|
308
|
-
# and have no sort defined on the criteria, use #take instead.
|
309
|
-
# Be aware that #take won't guarantee order.
|
310
|
-
#
|
311
|
-
# @param [ Integer ] limit The number of documents to return.
|
312
|
-
#
|
313
|
-
# @return [ Document ] The last document.
|
314
|
-
def last(limit = nil)
|
315
|
-
raw_docs = view.sort(inverse_sorting).limit(limit || 1).to_a.reverse
|
316
|
-
process_raw_docs(raw_docs, limit)
|
317
|
-
end
|
318
|
-
|
319
297
|
# Returns the number of documents in the database matching
|
320
298
|
# the query selector.
|
321
299
|
#
|
@@ -340,44 +318,6 @@ module Mongoid
|
|
340
318
|
@view = view.limit(value) and self
|
341
319
|
end
|
342
320
|
|
343
|
-
# Take the given number of documents from the database.
|
344
|
-
#
|
345
|
-
# @example Take 10 documents
|
346
|
-
# context.take(10)
|
347
|
-
#
|
348
|
-
# @param [ Integer | nil ] limit The number of documents to return or nil.
|
349
|
-
#
|
350
|
-
# @return [ Document | Array<Document> ] The list of documents, or one
|
351
|
-
# document if no value was given.
|
352
|
-
def take(limit = nil)
|
353
|
-
if limit
|
354
|
-
limit(limit).to_a
|
355
|
-
else
|
356
|
-
# Do to_a first so that the Mongo#first method is not used and the
|
357
|
-
# result is not sorted.
|
358
|
-
limit(1).to_a.first
|
359
|
-
end
|
360
|
-
end
|
361
|
-
|
362
|
-
# Take one document from the database and raise an error if there are none.
|
363
|
-
#
|
364
|
-
# @example Take a document
|
365
|
-
# context.take!
|
366
|
-
#
|
367
|
-
# @return [ Document ] The document.
|
368
|
-
#
|
369
|
-
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
370
|
-
# documents to take.
|
371
|
-
def take!
|
372
|
-
# Do to_a first so that the Mongo#first method is not used and the
|
373
|
-
# result is not sorted.
|
374
|
-
if fst = limit(1).to_a.first
|
375
|
-
fst
|
376
|
-
else
|
377
|
-
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
378
|
-
end
|
379
|
-
end
|
380
|
-
|
381
321
|
# Initiate a map/reduce operation from the context.
|
382
322
|
#
|
383
323
|
# @example Initiate a map/reduce.
|
@@ -391,15 +331,22 @@ module Mongoid
|
|
391
331
|
MapReduce.new(collection, criteria, map, reduce)
|
392
332
|
end
|
393
333
|
|
394
|
-
# Pluck the
|
395
|
-
#
|
334
|
+
# Pluck the field value(s) from the database. Returns one
|
335
|
+
# result for each document found in the database for
|
336
|
+
# the context. The results are normalized according to their
|
337
|
+
# Mongoid field types. Note that the results may include
|
338
|
+
# duplicates and nil values.
|
396
339
|
#
|
397
340
|
# @example Pluck a field.
|
398
341
|
# context.pluck(:_id)
|
399
342
|
#
|
400
|
-
# @param [ String | Symbol ] *fields Field(s) to pluck
|
343
|
+
# @param [ [ String | Symbol ]... ] *fields Field(s) to pluck,
|
344
|
+
# which may include nested fields using dot-notation.
|
401
345
|
#
|
402
346
|
# @return [ Array<Object> | Array<Array<Object>> ] The plucked values.
|
347
|
+
# If the *fields arg contains a single value, each result
|
348
|
+
# in the array will be a single value. Otherwise, each
|
349
|
+
# result in the array will be an array of values.
|
403
350
|
def pluck(*fields)
|
404
351
|
# Multiple fields can map to the same field name. For example, plucking
|
405
352
|
# a field and its _translations field map to the same field in the database.
|
@@ -434,13 +381,51 @@ module Mongoid
|
|
434
381
|
# @example Pick a field.
|
435
382
|
# context.pick(:_id)
|
436
383
|
#
|
437
|
-
# @param [ String | Symbol ] *fields Field(s) to pick.
|
384
|
+
# @param [ [ String | Symbol ]... ] *fields Field(s) to pick.
|
438
385
|
#
|
439
386
|
# @return [ Object | Array<Object> ] The picked values.
|
440
387
|
def pick(*fields)
|
441
388
|
limit(1).pluck(*fields).first
|
442
389
|
end
|
443
390
|
|
391
|
+
# Take the given number of documents from the database.
|
392
|
+
#
|
393
|
+
# @example Take 10 documents
|
394
|
+
# context.take(10)
|
395
|
+
#
|
396
|
+
# @param [ Integer | nil ] limit The number of documents to return or nil.
|
397
|
+
#
|
398
|
+
# @return [ Document | Array<Document> ] The list of documents, or one
|
399
|
+
# document if no value was given.
|
400
|
+
def take(limit = nil)
|
401
|
+
if limit
|
402
|
+
limit(limit).to_a
|
403
|
+
else
|
404
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
405
|
+
# result is not sorted.
|
406
|
+
limit(1).to_a.first
|
407
|
+
end
|
408
|
+
end
|
409
|
+
|
410
|
+
# Take one document from the database and raise an error if there are none.
|
411
|
+
#
|
412
|
+
# @example Take a document
|
413
|
+
# context.take!
|
414
|
+
#
|
415
|
+
# @return [ Document ] The document.
|
416
|
+
#
|
417
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
418
|
+
# documents to take.
|
419
|
+
def take!
|
420
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
421
|
+
# result is not sorted.
|
422
|
+
if fst = limit(1).to_a.first
|
423
|
+
fst
|
424
|
+
else
|
425
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
444
429
|
# Get a hash of counts for the values of a single field. For example,
|
445
430
|
# if the following documents were in the database:
|
446
431
|
#
|
@@ -553,7 +538,7 @@ module Mongoid
|
|
553
538
|
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
554
539
|
# an update should apply.
|
555
540
|
#
|
556
|
-
# @return [ nil
|
541
|
+
# @return [ nil | false ] False if no attributes were provided.
|
557
542
|
def update(attributes = nil, opts = {})
|
558
543
|
update_documents(attributes, :update_one, opts)
|
559
544
|
end
|
@@ -569,11 +554,255 @@ module Mongoid
|
|
569
554
|
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
570
555
|
# an update should apply.
|
571
556
|
#
|
572
|
-
# @return [ nil
|
557
|
+
# @return [ nil | false ] False if no attributes were provided.
|
573
558
|
def update_all(attributes = nil, opts = {})
|
574
559
|
update_documents(attributes, :update_many, opts)
|
575
560
|
end
|
576
561
|
|
562
|
+
# Get the first document in the database for the criteria's selector.
|
563
|
+
#
|
564
|
+
# @example Get the first document.
|
565
|
+
# context.first
|
566
|
+
#
|
567
|
+
# @note Automatically adding a sort on _id when no other sort is
|
568
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
569
|
+
# If you experience unexpected poor performance when using #first or #last
|
570
|
+
# and have no sort defined on the criteria, use #take instead.
|
571
|
+
# Be aware that #take won't guarantee order.
|
572
|
+
#
|
573
|
+
# @param [ Integer ] limit The number of documents to return.
|
574
|
+
#
|
575
|
+
# @return [ Document | nil ] The first document or nil if none is found.
|
576
|
+
def first(limit = nil)
|
577
|
+
if limit.nil?
|
578
|
+
retrieve_nth(0)
|
579
|
+
else
|
580
|
+
retrieve_nth_with_limit(0, limit)
|
581
|
+
end
|
582
|
+
end
|
583
|
+
alias :one :first
|
584
|
+
|
585
|
+
# Get the first document in the database for the criteria's selector or
|
586
|
+
# raise an error if none is found.
|
587
|
+
#
|
588
|
+
# @example Get the first document.
|
589
|
+
# context.first!
|
590
|
+
#
|
591
|
+
# @note Automatically adding a sort on _id when no other sort is
|
592
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
593
|
+
# If you experience unexpected poor performance when using #first! or #last!
|
594
|
+
# and have no sort defined on the criteria, use #take! instead.
|
595
|
+
# Be aware that #take! won't guarantee order.
|
596
|
+
#
|
597
|
+
# @return [ Document ] The first document.
|
598
|
+
#
|
599
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
600
|
+
# documents available.
|
601
|
+
def first!
|
602
|
+
first || raise_document_not_found_error
|
603
|
+
end
|
604
|
+
|
605
|
+
# Get the last document in the database for the criteria's selector.
|
606
|
+
#
|
607
|
+
# @example Get the last document.
|
608
|
+
# context.last
|
609
|
+
#
|
610
|
+
# @note Automatically adding a sort on _id when no other sort is
|
611
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
612
|
+
# If you experience unexpected poor performance when using #first or #last
|
613
|
+
# and have no sort defined on the criteria, use #take instead.
|
614
|
+
# Be aware that #take won't guarantee order.
|
615
|
+
#
|
616
|
+
# @param [ Integer ] limit The number of documents to return.
|
617
|
+
#
|
618
|
+
# @return [ Document | nil ] The last document or nil if none is found.
|
619
|
+
def last(limit = nil)
|
620
|
+
if limit.nil?
|
621
|
+
retrieve_nth_to_last(0)
|
622
|
+
else
|
623
|
+
retrieve_nth_to_last_with_limit(0, limit)
|
624
|
+
end
|
625
|
+
end
|
626
|
+
|
627
|
+
# Get the last document in the database for the criteria's selector or
|
628
|
+
# raise an error if none is found.
|
629
|
+
#
|
630
|
+
# @example Get the last document.
|
631
|
+
# context.last!
|
632
|
+
#
|
633
|
+
# @note Automatically adding a sort on _id when no other sort is
|
634
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
635
|
+
# If you experience unexpected poor performance when using #first! or #last!
|
636
|
+
# and have no sort defined on the criteria, use #take! instead.
|
637
|
+
# Be aware that #take! won't guarantee order.
|
638
|
+
#
|
639
|
+
# @return [ Document ] The last document.
|
640
|
+
#
|
641
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
642
|
+
# documents available.
|
643
|
+
def last!
|
644
|
+
last || raise_document_not_found_error
|
645
|
+
end
|
646
|
+
|
647
|
+
# Get the second document in the database for the criteria's selector.
|
648
|
+
#
|
649
|
+
# @example Get the second document.
|
650
|
+
# context.second
|
651
|
+
#
|
652
|
+
# @return [ Document | nil ] The second document or nil if none is found.
|
653
|
+
def second
|
654
|
+
retrieve_nth(1)
|
655
|
+
end
|
656
|
+
|
657
|
+
# Get the second document in the database for the criteria's selector or
|
658
|
+
# raise an error if none is found.
|
659
|
+
#
|
660
|
+
# @example Get the second document.
|
661
|
+
# context.second!
|
662
|
+
#
|
663
|
+
# @return [ Document ] The second document.
|
664
|
+
#
|
665
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
666
|
+
# documents available.
|
667
|
+
def second!
|
668
|
+
second || raise_document_not_found_error
|
669
|
+
end
|
670
|
+
|
671
|
+
# Get the third document in the database for the criteria's selector.
|
672
|
+
#
|
673
|
+
# @example Get the third document.
|
674
|
+
# context.third
|
675
|
+
#
|
676
|
+
# @return [ Document | nil ] The third document or nil if none is found.
|
677
|
+
def third
|
678
|
+
retrieve_nth(2)
|
679
|
+
end
|
680
|
+
|
681
|
+
# Get the third document in the database for the criteria's selector or
|
682
|
+
# raise an error if none is found.
|
683
|
+
#
|
684
|
+
# @example Get the third document.
|
685
|
+
# context.third!
|
686
|
+
#
|
687
|
+
# @return [ Document ] The third document.
|
688
|
+
#
|
689
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
690
|
+
# documents available.
|
691
|
+
def third!
|
692
|
+
third || raise_document_not_found_error
|
693
|
+
end
|
694
|
+
|
695
|
+
# Get the fourth document in the database for the criteria's selector.
|
696
|
+
#
|
697
|
+
# @example Get the fourth document.
|
698
|
+
# context.fourth
|
699
|
+
#
|
700
|
+
# @return [ Document | nil ] The fourth document or nil if none is found.
|
701
|
+
def fourth
|
702
|
+
retrieve_nth(3)
|
703
|
+
end
|
704
|
+
|
705
|
+
# Get the fourth document in the database for the criteria's selector or
|
706
|
+
# raise an error if none is found.
|
707
|
+
#
|
708
|
+
# @example Get the fourth document.
|
709
|
+
# context.fourth!
|
710
|
+
#
|
711
|
+
# @return [ Document ] The fourth document.
|
712
|
+
#
|
713
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
714
|
+
# documents available.
|
715
|
+
def fourth!
|
716
|
+
fourth || raise_document_not_found_error
|
717
|
+
end
|
718
|
+
|
719
|
+
# Get the fifth document in the database for the criteria's selector.
|
720
|
+
#
|
721
|
+
# @example Get the fifth document.
|
722
|
+
# context.fifth
|
723
|
+
#
|
724
|
+
# @return [ Document | nil ] The fifth document or nil if none is found.
|
725
|
+
def fifth
|
726
|
+
retrieve_nth(4)
|
727
|
+
end
|
728
|
+
|
729
|
+
# Get the fifth document in the database for the criteria's selector or
|
730
|
+
# raise an error if none is found.
|
731
|
+
#
|
732
|
+
# @example Get the fifth document.
|
733
|
+
# context.fifth!
|
734
|
+
#
|
735
|
+
# @return [ Document ] The fifth document.
|
736
|
+
#
|
737
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
738
|
+
# documents available.
|
739
|
+
def fifth!
|
740
|
+
fifth || raise_document_not_found_error
|
741
|
+
end
|
742
|
+
|
743
|
+
# Get the second to last document in the database for the criteria's
|
744
|
+
# selector.
|
745
|
+
#
|
746
|
+
# @example Get the second to last document.
|
747
|
+
# context.second_to_last
|
748
|
+
#
|
749
|
+
# @return [ Document | nil ] The second to last document or nil if none
|
750
|
+
# is found.
|
751
|
+
def second_to_last
|
752
|
+
retrieve_nth_to_last(1)
|
753
|
+
end
|
754
|
+
|
755
|
+
# Get the second to last document in the database for the criteria's
|
756
|
+
# selector or raise an error if none is found.
|
757
|
+
#
|
758
|
+
# @example Get the second to last document.
|
759
|
+
# context.second_to_last!
|
760
|
+
#
|
761
|
+
# @return [ Document ] The second to last document.
|
762
|
+
#
|
763
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
764
|
+
# documents available.
|
765
|
+
def second_to_last!
|
766
|
+
second_to_last || raise_document_not_found_error
|
767
|
+
end
|
768
|
+
|
769
|
+
# Get the third to last document in the database for the criteria's
|
770
|
+
# selector.
|
771
|
+
#
|
772
|
+
# @example Get the third to last document.
|
773
|
+
# context.third_to_last
|
774
|
+
#
|
775
|
+
# @return [ Document | nil ] The third to last document or nil if none
|
776
|
+
# is found.
|
777
|
+
def third_to_last
|
778
|
+
retrieve_nth_to_last(2)
|
779
|
+
end
|
780
|
+
|
781
|
+
# Get the third to last document in the database for the criteria's
|
782
|
+
# selector or raise an error if none is found.
|
783
|
+
#
|
784
|
+
# @example Get the third to last document.
|
785
|
+
# context.third_to_last!
|
786
|
+
#
|
787
|
+
# @return [ Document ] The third to last document.
|
788
|
+
#
|
789
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
790
|
+
# documents available.
|
791
|
+
def third_to_last!
|
792
|
+
third_to_last || raise_document_not_found_error
|
793
|
+
end
|
794
|
+
|
795
|
+
# Schedule a task to load documents for the context.
|
796
|
+
#
|
797
|
+
# Depending on the Mongoid configuration, the scheduled task can be executed
|
798
|
+
# immediately on the caller's thread, or can be scheduled for an
|
799
|
+
# asynchronous execution.
|
800
|
+
#
|
801
|
+
# @api private
|
802
|
+
def load_async
|
803
|
+
@documents_loader ||= DocumentsLoader.new(view, klass, criteria)
|
804
|
+
end
|
805
|
+
|
577
806
|
private
|
578
807
|
|
579
808
|
# Update the documents for the provided method.
|
@@ -641,24 +870,29 @@ module Mongoid
|
|
641
870
|
Hash[sort.map{|k, v| [k, -1*v]}]
|
642
871
|
end
|
643
872
|
|
644
|
-
# Get the documents the context should iterate.
|
873
|
+
# Get the documents the context should iterate.
|
645
874
|
#
|
646
|
-
#
|
647
|
-
#
|
648
|
-
# 2. If we are eager loading, then eager load the documents and use
|
649
|
-
# those.
|
650
|
-
# 3. Use the query.
|
651
|
-
#
|
652
|
-
# @api private
|
653
|
-
#
|
654
|
-
# @example Get the documents for iteration.
|
655
|
-
# context.documents_for_iteration
|
875
|
+
# If the documents have been already preloaded by `Document::Loader`
|
876
|
+
# instance, they will be used.
|
656
877
|
#
|
657
878
|
# @return [ Array<Document> | Mongo::Collection::View ] The docs to iterate.
|
879
|
+
#
|
880
|
+
# @api private
|
658
881
|
def documents_for_iteration
|
659
|
-
|
660
|
-
|
661
|
-
|
882
|
+
if @documents_loader
|
883
|
+
if @documents_loader.started?
|
884
|
+
@documents_loader.value!
|
885
|
+
else
|
886
|
+
@documents_loader.unschedule
|
887
|
+
@documents_loader.execute
|
888
|
+
end
|
889
|
+
else
|
890
|
+
return view unless eager_loadable?
|
891
|
+
docs = view.map do |doc|
|
892
|
+
Factory.from_db(klass, doc, criteria)
|
893
|
+
end
|
894
|
+
eager_load(docs)
|
895
|
+
end
|
662
896
|
end
|
663
897
|
|
664
898
|
# Yield to the document.
|
@@ -677,8 +911,6 @@ module Mongoid
|
|
677
911
|
yield(doc)
|
678
912
|
end
|
679
913
|
|
680
|
-
private
|
681
|
-
|
682
914
|
def _session
|
683
915
|
@criteria.send(:_session)
|
684
916
|
end
|
@@ -813,6 +1045,34 @@ module Mongoid
|
|
813
1045
|
docs = eager_load(docs)
|
814
1046
|
limit ? docs : docs.first
|
815
1047
|
end
|
1048
|
+
|
1049
|
+
def raise_document_not_found_error
|
1050
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
1051
|
+
end
|
1052
|
+
|
1053
|
+
def retrieve_nth(n)
|
1054
|
+
retrieve_nth_with_limit(n, 1).first
|
1055
|
+
end
|
1056
|
+
|
1057
|
+
def retrieve_nth_with_limit(n, limit)
|
1058
|
+
sort = view.sort || { _id: 1 }
|
1059
|
+
v = view.sort(sort).limit(limit || 1)
|
1060
|
+
v = v.skip(n) if n > 0
|
1061
|
+
if raw_docs = v.to_a
|
1062
|
+
process_raw_docs(raw_docs, limit)
|
1063
|
+
end
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
def retrieve_nth_to_last(n)
|
1067
|
+
retrieve_nth_to_last_with_limit(n, 1).first
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
def retrieve_nth_to_last_with_limit(n, limit)
|
1071
|
+
v = view.sort(inverse_sorting).skip(n).limit(limit || 1)
|
1072
|
+
v = v.skip(n) if n > 0
|
1073
|
+
raw_docs = v.to_a.reverse
|
1074
|
+
process_raw_docs(raw_docs, limit)
|
1075
|
+
end
|
816
1076
|
end
|
817
1077
|
end
|
818
1078
|
end
|