mongoid 8.0.6 → 8.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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/macros.rb +0 -6
- 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/processing.rb +5 -29
- 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/options.rb +0 -3
- data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +99 -15
- 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/queryable/selector.rb +1 -1
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- 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/hash.rb +2 -6
- 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 +53 -24
- 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 -33
- 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 -27
- 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 +1006 -77
- 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 +3 -76
- data/spec/mongoid/criteria/queryable/storable_spec.rb +0 -72
- 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/hash_spec.rb +3 -3
- 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 -77
- 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/lite_constraints.rb +2 -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 +28 -4
- 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/person.rb +0 -1
- data/spec/support/models/product.rb +1 -0
- data.tar.gz.sig +0 -0
- metadata +686 -652
- 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
- data/spec/support/models/purse.rb +0 -9
@@ -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
|