mongoid 2.4.10 → 3.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.
- data/CHANGELOG.md +949 -10
- data/LICENSE +1 -1
- data/README.md +10 -11
- data/Rakefile +3 -17
- data/lib/config/locales/en.yml +455 -51
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic/paths/embedded/many.rb +6 -6
- data/lib/mongoid/atomic/paths/embedded/one.rb +5 -5
- data/lib/mongoid/atomic/paths/embedded.rb +4 -5
- data/lib/mongoid/atomic/paths/root.rb +4 -5
- data/lib/mongoid/atomic.rb +70 -16
- data/lib/mongoid/attributes/processing.rb +14 -10
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/attributes.rb +95 -32
- data/lib/mongoid/callbacks.rb +106 -43
- data/lib/mongoid/components.rb +12 -23
- data/lib/mongoid/config/environment.rb +7 -4
- data/lib/mongoid/config/inflections.rb +6 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config.rb +104 -225
- data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +181 -0
- data/lib/mongoid/contextual/atomic.rb +179 -0
- data/lib/mongoid/contextual/command.rb +43 -0
- data/lib/mongoid/contextual/find_and_modify.rb +68 -0
- data/lib/mongoid/contextual/map_reduce.rb +273 -0
- data/lib/mongoid/contextual/memory.rb +406 -0
- data/lib/mongoid/contextual/mongo.rb +662 -0
- data/lib/mongoid/contextual.rb +50 -0
- data/lib/mongoid/copyable.rb +7 -25
- data/lib/mongoid/criteria.rb +515 -245
- data/lib/mongoid/criterion/inspection.rb +14 -8
- data/lib/mongoid/criterion/scoping.rb +114 -44
- data/lib/mongoid/dirty.rb +152 -67
- data/lib/mongoid/document.rb +71 -52
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +5 -6
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +98 -17
- data/lib/mongoid/errors/eager_load.rb +3 -6
- data/lib/mongoid/errors/invalid_collection.rb +3 -3
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_database.rb +3 -3
- data/lib/mongoid/errors/invalid_field.rb +54 -8
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +3 -3
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +4 -4
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +3 -6
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +4 -9
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +54 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +3 -3
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_metadata.rb +21 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +4 -4
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +4 -4
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +4 -8
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/unsupported_version.rb +4 -4
- data/lib/mongoid/errors/validations.rb +7 -6
- data/lib/mongoid/errors/versioning_not_on_root.rb +23 -0
- data/lib/mongoid/errors.rb +23 -1
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions/array.rb +164 -0
- data/lib/mongoid/extensions/big_decimal.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +24 -0
- data/lib/mongoid/extensions/date.rb +70 -0
- data/lib/mongoid/extensions/date_time.rb +73 -0
- data/lib/mongoid/extensions/false_class.rb +38 -0
- data/lib/mongoid/extensions/float.rb +56 -0
- data/lib/mongoid/extensions/hash.rb +123 -0
- data/lib/mongoid/extensions/integer.rb +66 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +21 -0
- data/lib/mongoid/extensions/object.rb +238 -0
- data/lib/mongoid/extensions/object_id.rb +54 -0
- data/lib/mongoid/extensions/range.rb +79 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +181 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +78 -0
- data/lib/mongoid/extensions/time_with_zone.rb +55 -0
- data/lib/mongoid/extensions/true_class.rb +38 -0
- data/lib/mongoid/extensions.rb +28 -76
- data/lib/mongoid/factory.rb +1 -1
- data/lib/mongoid/fields/foreign_key.rb +150 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +268 -0
- data/lib/mongoid/fields/validators/macro.rb +83 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields.rb +142 -208
- data/lib/mongoid/finders.rb +45 -50
- data/lib/mongoid/hierarchy.rb +44 -15
- data/lib/mongoid/identity_map.rb +49 -21
- data/lib/mongoid/indexes/validators/options.rb +80 -0
- data/lib/mongoid/indexes.rb +66 -15
- data/lib/mongoid/inspection.rb +1 -1
- data/lib/mongoid/json.rb +2 -2
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchers/all.rb +7 -8
- data/lib/mongoid/matchers/and.rb +3 -3
- data/lib/mongoid/matchers/default.rb +6 -4
- data/lib/mongoid/matchers/exists.rb +2 -2
- data/lib/mongoid/matchers/gt.rb +2 -2
- data/lib/mongoid/matchers/gte.rb +2 -2
- data/lib/mongoid/matchers/in.rb +3 -7
- data/lib/mongoid/matchers/lt.rb +2 -2
- data/lib/mongoid/matchers/lte.rb +2 -2
- data/lib/mongoid/matchers/ne.rb +2 -2
- data/lib/mongoid/matchers/nin.rb +2 -2
- data/lib/mongoid/matchers/or.rb +2 -2
- data/lib/mongoid/matchers/size.rb +2 -2
- data/lib/mongoid/matchers/strategies.rb +3 -3
- data/lib/mongoid/matchers.rb +1 -1
- data/lib/mongoid/multi_parameter_attributes.rb +9 -11
- data/lib/mongoid/nested_attributes.rb +17 -9
- data/lib/mongoid/observer.rb +1 -2
- data/lib/mongoid/paranoia.rb +10 -44
- data/lib/mongoid/persistence/atomic/add_to_set.rb +5 -9
- data/lib/mongoid/persistence/atomic/bit.rb +5 -7
- data/lib/mongoid/persistence/atomic/inc.rb +5 -7
- data/lib/mongoid/persistence/atomic/operation.rb +45 -6
- data/lib/mongoid/persistence/atomic/pop.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull.rb +5 -7
- data/lib/mongoid/persistence/atomic/pull_all.rb +5 -7
- data/lib/mongoid/persistence/atomic/push.rb +4 -10
- data/lib/mongoid/persistence/atomic/push_all.rb +4 -10
- data/lib/mongoid/persistence/atomic/rename.rb +6 -7
- data/lib/mongoid/persistence/atomic/sets.rb +5 -7
- data/lib/mongoid/persistence/atomic/unset.rb +4 -5
- data/lib/mongoid/persistence/atomic.rb +2 -2
- data/lib/mongoid/persistence/deletion.rb +2 -2
- data/lib/mongoid/persistence/insertion.rb +10 -16
- data/lib/mongoid/persistence/modification.rb +5 -9
- data/lib/mongoid/persistence/operations/embedded/insert.rb +7 -6
- data/lib/mongoid/persistence/operations/embedded/remove.rb +5 -5
- data/lib/mongoid/persistence/operations/insert.rb +4 -4
- data/lib/mongoid/persistence/operations/remove.rb +4 -4
- data/lib/mongoid/persistence/operations/update.rb +5 -5
- data/lib/mongoid/persistence/operations/upsert.rb +28 -0
- data/lib/mongoid/persistence/operations.rb +22 -19
- data/lib/mongoid/persistence/upsertion.rb +30 -0
- data/lib/mongoid/persistence.rb +94 -39
- data/lib/mongoid/railtie.rb +26 -11
- data/lib/mongoid/railties/database.rake +22 -108
- data/lib/mongoid/relations/accessors.rb +120 -20
- data/lib/mongoid/relations/auto_save.rb +59 -5
- data/lib/mongoid/relations/binding.rb +211 -2
- data/lib/mongoid/relations/bindings/embedded/in.rb +16 -22
- data/lib/mongoid/relations/bindings/embedded/many.rb +9 -50
- data/lib/mongoid/relations/bindings/embedded/one.rb +10 -16
- data/lib/mongoid/relations/bindings/referenced/in.rb +31 -57
- data/lib/mongoid/relations/bindings/referenced/many.rb +8 -20
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +15 -19
- data/lib/mongoid/relations/bindings/referenced/one.rb +10 -24
- data/lib/mongoid/relations/builder.rb +4 -4
- data/lib/mongoid/relations/builders/embedded/in.rb +5 -5
- data/lib/mongoid/relations/builders/embedded/many.rb +12 -12
- data/lib/mongoid/relations/builders/embedded/one.rb +6 -6
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +8 -8
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -5
- data/lib/mongoid/relations/builders/referenced/in.rb +4 -4
- data/lib/mongoid/relations/builders/referenced/many.rb +6 -6
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +7 -5
- data/lib/mongoid/relations/builders/referenced/one.rb +5 -5
- data/lib/mongoid/relations/builders.rb +19 -16
- data/lib/mongoid/relations/cascading/delete.rb +3 -5
- data/lib/mongoid/relations/cascading/destroy.rb +3 -3
- data/lib/mongoid/relations/cascading/nullify.rb +3 -3
- data/lib/mongoid/relations/cascading/restrict.rb +37 -0
- data/lib/mongoid/relations/cascading.rb +10 -7
- data/lib/mongoid/relations/constraint.rb +4 -3
- data/lib/mongoid/relations/conversions.rb +6 -7
- data/lib/mongoid/relations/cyclic.rb +7 -7
- data/lib/mongoid/relations/embedded/batchable.rb +347 -0
- data/lib/mongoid/relations/embedded/in.rb +23 -12
- data/lib/mongoid/relations/embedded/many.rb +100 -161
- data/lib/mongoid/relations/embedded/one.rb +25 -14
- data/lib/mongoid/relations/macros.rb +105 -60
- data/lib/mongoid/relations/many.rb +93 -14
- data/lib/mongoid/relations/metadata.rb +277 -47
- data/lib/mongoid/relations/nested_builder.rb +4 -6
- data/lib/mongoid/relations/one.rb +2 -2
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/polymorphic.rb +9 -9
- data/lib/mongoid/relations/proxy.rb +62 -31
- data/lib/mongoid/relations/referenced/in.rb +40 -15
- data/lib/mongoid/relations/referenced/many.rb +162 -130
- data/lib/mongoid/relations/referenced/many_to_many.rb +104 -48
- data/lib/mongoid/relations/referenced/one.rb +34 -13
- data/lib/mongoid/relations/reflections.rb +3 -3
- data/lib/mongoid/relations/synchronization.rb +19 -23
- data/lib/mongoid/relations/targets/enumerable.rb +86 -57
- data/lib/mongoid/relations/touchable.rb +32 -0
- data/lib/mongoid/relations.rb +22 -6
- data/lib/mongoid/reloading.rb +12 -14
- data/lib/mongoid/scoping.rb +312 -0
- data/lib/mongoid/serialization.rb +94 -42
- data/lib/mongoid/sessions/factory.rb +108 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions.rb +383 -0
- data/lib/mongoid/sharding.rb +6 -6
- data/lib/mongoid/state.rb +6 -7
- data/lib/mongoid/threaded/lifecycle.rb +21 -21
- data/lib/mongoid/threaded/sessions.rb +0 -0
- data/lib/mongoid/threaded.rb +219 -59
- data/lib/mongoid/timestamps/created.rb +8 -4
- data/lib/mongoid/timestamps/timeless.rb +6 -4
- data/lib/mongoid/timestamps/updated.rb +4 -3
- data/lib/mongoid/timestamps.rb +1 -1
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validations/associated.rb +2 -2
- data/lib/mongoid/validations/format.rb +2 -2
- data/lib/mongoid/validations/presence.rb +34 -4
- data/lib/mongoid/validations/uniqueness.rb +11 -12
- data/lib/mongoid/validations.rb +28 -20
- data/lib/mongoid/version.rb +2 -2
- data/lib/mongoid/versioning.rb +25 -26
- data/lib/mongoid.rb +37 -37
- data/lib/rack/mongoid/middleware/identity_map.rb +3 -3
- data/lib/rails/generators/mongoid/config/config_generator.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +65 -17
- data/lib/rails/generators/mongoid/model/model_generator.rb +7 -7
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +2 -2
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +4 -4
- data/lib/rails/generators/mongoid_generator.rb +5 -5
- data/lib/rails/mongoid.rb +73 -26
- metadata +103 -148
- data/lib/config/locales/bg.yml +0 -61
- data/lib/config/locales/de.yml +0 -61
- data/lib/config/locales/en-GB.yml +0 -64
- data/lib/config/locales/es.yml +0 -59
- data/lib/config/locales/fr.yml +0 -62
- data/lib/config/locales/hi.yml +0 -53
- data/lib/config/locales/hu.yml +0 -64
- data/lib/config/locales/id.yml +0 -62
- data/lib/config/locales/it.yml +0 -59
- data/lib/config/locales/ja.yml +0 -57
- data/lib/config/locales/kr.yml +0 -54
- data/lib/config/locales/nl.yml +0 -61
- data/lib/config/locales/pl.yml +0 -59
- data/lib/config/locales/pt-BR.yml +0 -60
- data/lib/config/locales/pt.yml +0 -60
- data/lib/config/locales/ro.yml +0 -66
- data/lib/config/locales/ru.yml +0 -61
- data/lib/config/locales/sv.yml +0 -60
- data/lib/config/locales/vi.yml +0 -62
- data/lib/config/locales/zh-CN.yml +0 -53
- data/lib/mongoid/collection.rb +0 -157
- data/lib/mongoid/collections/master.rb +0 -45
- data/lib/mongoid/collections/operations.rb +0 -44
- data/lib/mongoid/collections/retry.rb +0 -59
- data/lib/mongoid/collections.rb +0 -120
- data/lib/mongoid/config/database.rb +0 -181
- data/lib/mongoid/config/replset_database.rb +0 -80
- data/lib/mongoid/contexts/enumerable/sort.rb +0 -43
- data/lib/mongoid/contexts/enumerable.rb +0 -313
- data/lib/mongoid/contexts/mongo.rb +0 -487
- data/lib/mongoid/contexts.rb +0 -25
- data/lib/mongoid/criterion/builder.rb +0 -34
- data/lib/mongoid/criterion/complex.rb +0 -84
- data/lib/mongoid/criterion/creational.rb +0 -34
- data/lib/mongoid/criterion/exclusion.rb +0 -108
- data/lib/mongoid/criterion/inclusion.rb +0 -290
- data/lib/mongoid/criterion/optional.rb +0 -259
- data/lib/mongoid/criterion/selector.rb +0 -177
- data/lib/mongoid/cursor.rb +0 -88
- data/lib/mongoid/default_scope.rb +0 -36
- data/lib/mongoid/errors/invalid_type.rb +0 -25
- data/lib/mongoid/extensions/array/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/array/deletion.rb +0 -29
- data/lib/mongoid/extensions/false_class/equality.rb +0 -26
- data/lib/mongoid/extensions/hash/criteria_helpers.rb +0 -47
- data/lib/mongoid/extensions/hash/deep_copy.rb +0 -25
- data/lib/mongoid/extensions/hash/scoping.rb +0 -25
- data/lib/mongoid/extensions/integer/checks.rb +0 -23
- data/lib/mongoid/extensions/nil/collectionization.rb +0 -23
- data/lib/mongoid/extensions/object/checks.rb +0 -29
- data/lib/mongoid/extensions/object/deep_copy.rb +0 -21
- data/lib/mongoid/extensions/object/reflections.rb +0 -48
- data/lib/mongoid/extensions/object/substitutable.rb +0 -15
- data/lib/mongoid/extensions/object/yoda.rb +0 -44
- data/lib/mongoid/extensions/object_id/conversions.rb +0 -60
- data/lib/mongoid/extensions/proc/scoping.rb +0 -25
- data/lib/mongoid/extensions/string/checks.rb +0 -36
- data/lib/mongoid/extensions/string/conversions.rb +0 -22
- data/lib/mongoid/extensions/string/inflections.rb +0 -118
- data/lib/mongoid/extensions/symbol/checks.rb +0 -23
- data/lib/mongoid/extensions/symbol/inflections.rb +0 -67
- data/lib/mongoid/extensions/true_class/equality.rb +0 -26
- data/lib/mongoid/extras.rb +0 -31
- data/lib/mongoid/fields/internal/array.rb +0 -76
- data/lib/mongoid/fields/internal/big_decimal.rb +0 -63
- data/lib/mongoid/fields/internal/bignum.rb +0 -10
- data/lib/mongoid/fields/internal/binary.rb +0 -11
- data/lib/mongoid/fields/internal/boolean.rb +0 -58
- data/lib/mongoid/fields/internal/date.rb +0 -51
- data/lib/mongoid/fields/internal/date_time.rb +0 -28
- data/lib/mongoid/fields/internal/false_class.rb +0 -10
- data/lib/mongoid/fields/internal/fixnum.rb +0 -10
- data/lib/mongoid/fields/internal/float.rb +0 -47
- data/lib/mongoid/fields/internal/foreign_keys/array.rb +0 -88
- data/lib/mongoid/fields/internal/foreign_keys/object.rb +0 -56
- data/lib/mongoid/fields/internal/hash.rb +0 -11
- data/lib/mongoid/fields/internal/integer.rb +0 -59
- data/lib/mongoid/fields/internal/localized.rb +0 -62
- data/lib/mongoid/fields/internal/nil_class.rb +0 -53
- data/lib/mongoid/fields/internal/object.rb +0 -11
- data/lib/mongoid/fields/internal/object_id.rb +0 -46
- data/lib/mongoid/fields/internal/range.rb +0 -61
- data/lib/mongoid/fields/internal/set.rb +0 -57
- data/lib/mongoid/fields/internal/string.rb +0 -42
- data/lib/mongoid/fields/internal/symbol.rb +0 -43
- data/lib/mongoid/fields/internal/time.rb +0 -23
- data/lib/mongoid/fields/internal/time_with_zone.rb +0 -23
- data/lib/mongoid/fields/internal/timekeeping.rb +0 -122
- data/lib/mongoid/fields/internal/true_class.rb +0 -10
- data/lib/mongoid/fields/mappings.rb +0 -42
- data/lib/mongoid/fields/serializable.rb +0 -270
- data/lib/mongoid/identity.rb +0 -92
- data/lib/mongoid/javascript/functions.yml +0 -63
- data/lib/mongoid/javascript.rb +0 -20
- data/lib/mongoid/keys.rb +0 -144
- data/lib/mongoid/logger.rb +0 -45
- data/lib/mongoid/multi_database.rb +0 -36
- data/lib/mongoid/named_scope.rb +0 -166
- data/lib/mongoid/relations/embedded/atomic/operation.rb +0 -63
- data/lib/mongoid/relations/embedded/atomic/pull.rb +0 -65
- data/lib/mongoid/relations/embedded/atomic/push_all.rb +0 -59
- data/lib/mongoid/relations/embedded/atomic/set.rb +0 -61
- data/lib/mongoid/relations/embedded/atomic/unset.rb +0 -41
- data/lib/mongoid/relations/embedded/atomic.rb +0 -89
- data/lib/mongoid/relations/referenced/batch/insert.rb +0 -57
- data/lib/mongoid/relations/referenced/batch.rb +0 -73
- data/lib/mongoid/safety.rb +0 -105
- data/lib/mongoid/scope.rb +0 -31
|
@@ -0,0 +1,662 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/contextual/atomic"
|
|
3
|
+
require "mongoid/contextual/aggregable/mongo"
|
|
4
|
+
require "mongoid/contextual/command"
|
|
5
|
+
require "mongoid/contextual/find_and_modify"
|
|
6
|
+
require "mongoid/contextual/map_reduce"
|
|
7
|
+
|
|
8
|
+
module Mongoid
|
|
9
|
+
module Contextual
|
|
10
|
+
class Mongo
|
|
11
|
+
include Enumerable
|
|
12
|
+
include Aggregable::Mongo
|
|
13
|
+
include Atomic
|
|
14
|
+
|
|
15
|
+
# @attribute [r] criteria The criteria for the context.
|
|
16
|
+
# @attribute [r] klass The klass for the criteria.
|
|
17
|
+
# @attribute [r] query The Moped query.
|
|
18
|
+
attr_reader :criteria, :klass, :query
|
|
19
|
+
|
|
20
|
+
# @attribute [rw] eager_loaded Has the context been eager loaded?
|
|
21
|
+
attr_accessor :eager_loaded
|
|
22
|
+
|
|
23
|
+
# Is the enumerable of matching documents empty?
|
|
24
|
+
#
|
|
25
|
+
# @example Is the context empty?
|
|
26
|
+
# context.blank?
|
|
27
|
+
#
|
|
28
|
+
# @return [ true, false ] If the context is empty.
|
|
29
|
+
#
|
|
30
|
+
# @since 3.0.0
|
|
31
|
+
def blank?
|
|
32
|
+
count == 0
|
|
33
|
+
end
|
|
34
|
+
alias :empty? :blank?
|
|
35
|
+
|
|
36
|
+
# Is the context cached?
|
|
37
|
+
#
|
|
38
|
+
# @example Is the context cached?
|
|
39
|
+
# context.cached?
|
|
40
|
+
#
|
|
41
|
+
# @return [ true, false ] If the context is cached.
|
|
42
|
+
#
|
|
43
|
+
# @since 3.0.0
|
|
44
|
+
def cached?
|
|
45
|
+
!!@cache
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Get the number of documents matching the query.
|
|
49
|
+
#
|
|
50
|
+
# @example Get the number of matching documents.
|
|
51
|
+
# context.count
|
|
52
|
+
#
|
|
53
|
+
# @example Get the count of documents matching the provided.
|
|
54
|
+
# context.count(document)
|
|
55
|
+
#
|
|
56
|
+
# @example Get the count for where the provided block is true.
|
|
57
|
+
# context.count do |doc|
|
|
58
|
+
# doc.likes > 1
|
|
59
|
+
# end
|
|
60
|
+
#
|
|
61
|
+
# @param [ Document ] document A document ot match.
|
|
62
|
+
#
|
|
63
|
+
# @return [ Integer ] The number of matches.
|
|
64
|
+
#
|
|
65
|
+
# @since 3.0.0
|
|
66
|
+
def count(document = nil, &block)
|
|
67
|
+
return super(&block) if block_given?
|
|
68
|
+
return query.count unless document
|
|
69
|
+
klass.collection.find(criteria.and(_id: document.id).selector).count
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Delete all documents in the database that match the selector.
|
|
73
|
+
#
|
|
74
|
+
# @example Delete all the documents.
|
|
75
|
+
# context.delete
|
|
76
|
+
#
|
|
77
|
+
# @return [ nil ] Nil.
|
|
78
|
+
#
|
|
79
|
+
# @since 3.0.0
|
|
80
|
+
def delete
|
|
81
|
+
query.count.tap do
|
|
82
|
+
query.remove_all
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
alias :delete_all :delete
|
|
86
|
+
|
|
87
|
+
# Destroy all documents in the database that match the selector.
|
|
88
|
+
#
|
|
89
|
+
# @example Destroy all the documents.
|
|
90
|
+
# context.destroy
|
|
91
|
+
#
|
|
92
|
+
# @return [ nil ] Nil.
|
|
93
|
+
#
|
|
94
|
+
# @since 3.0.0
|
|
95
|
+
def destroy
|
|
96
|
+
destroyed = query.count
|
|
97
|
+
each do |doc|
|
|
98
|
+
doc.destroy
|
|
99
|
+
end
|
|
100
|
+
destroyed
|
|
101
|
+
end
|
|
102
|
+
alias :destroy_all :destroy
|
|
103
|
+
|
|
104
|
+
# Get the distinct values in the db for the provided field.
|
|
105
|
+
#
|
|
106
|
+
# @example Get the distinct values.
|
|
107
|
+
# context.distinct(:name)
|
|
108
|
+
#
|
|
109
|
+
# @param [ String, Symbol ] field The name of the field.
|
|
110
|
+
#
|
|
111
|
+
# @return [ Array<Object> ] The distinct values for the field.
|
|
112
|
+
#
|
|
113
|
+
# @since 3.0.0
|
|
114
|
+
def distinct(field)
|
|
115
|
+
query.distinct(field)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# Iterate over the context. If provided a block, yield to a Mongoid
|
|
119
|
+
# document for each, otherwise return an enum.
|
|
120
|
+
#
|
|
121
|
+
# @example Iterate over the context.
|
|
122
|
+
# context.each do |doc|
|
|
123
|
+
# puts doc.name
|
|
124
|
+
# end
|
|
125
|
+
#
|
|
126
|
+
# @return [ Enumerator ] The enumerator.
|
|
127
|
+
#
|
|
128
|
+
# @since 3.0.0
|
|
129
|
+
def each(&block)
|
|
130
|
+
if block_given?
|
|
131
|
+
reset_length
|
|
132
|
+
selecting do
|
|
133
|
+
documents_for_iteration.each do |doc|
|
|
134
|
+
yield_and_increment(doc, &block)
|
|
135
|
+
end
|
|
136
|
+
@cache_loaded = true
|
|
137
|
+
eager_loadable? ? docs : self
|
|
138
|
+
end
|
|
139
|
+
else
|
|
140
|
+
to_enum
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Do any documents exist for the context.
|
|
145
|
+
#
|
|
146
|
+
# @example Do any documents exist for the context.
|
|
147
|
+
# context.exists?
|
|
148
|
+
#
|
|
149
|
+
# @return [ true, false ] If the count is more than zero.
|
|
150
|
+
#
|
|
151
|
+
# @since 3.0.0
|
|
152
|
+
def exists?
|
|
153
|
+
count > 0
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Run an explain on the criteria.
|
|
157
|
+
#
|
|
158
|
+
# @example Explain the criteria.
|
|
159
|
+
# Band.where(name: "Depeche Mode").explain
|
|
160
|
+
#
|
|
161
|
+
# @return [ Hash ] The explain result.
|
|
162
|
+
#
|
|
163
|
+
# @since 3.0.0
|
|
164
|
+
def explain
|
|
165
|
+
query.explain
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# Execute the find and modify command, used for MongoDB's
|
|
169
|
+
# $findAndModify.
|
|
170
|
+
#
|
|
171
|
+
# @example Execute the command.
|
|
172
|
+
# context.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
|
|
173
|
+
#
|
|
174
|
+
# @param [ Hash ] update The updates.
|
|
175
|
+
# @param [ Hash ] options The command options.
|
|
176
|
+
#
|
|
177
|
+
# @option options [ true, false ] :new Return the updated document.
|
|
178
|
+
# @option options [ true, false ] :remove Delete the first document.
|
|
179
|
+
# @option options [ true, false ] :upsert Create the document if it doesn't exist.
|
|
180
|
+
#
|
|
181
|
+
# @return [ Document ] The result of the command.
|
|
182
|
+
#
|
|
183
|
+
# @since 3.0.0
|
|
184
|
+
def find_and_modify(update, options = {})
|
|
185
|
+
if doc = FindAndModify.new(criteria, update, options).result
|
|
186
|
+
Factory.from_db(klass, doc)
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
# Get the first document in the database for the criteria's selector.
|
|
191
|
+
#
|
|
192
|
+
# @example Get the first document.
|
|
193
|
+
# context.first
|
|
194
|
+
#
|
|
195
|
+
# @return [ Document ] The first document.
|
|
196
|
+
#
|
|
197
|
+
# @since 3.0.0
|
|
198
|
+
def first
|
|
199
|
+
with_eager_loading(query.first)
|
|
200
|
+
end
|
|
201
|
+
alias :one :first
|
|
202
|
+
|
|
203
|
+
# Create the new Mongo context. This delegates operations to the
|
|
204
|
+
# underlying driver - in Mongoid's case Moped.
|
|
205
|
+
#
|
|
206
|
+
# @example Create the new context.
|
|
207
|
+
# Mongo.new(criteria)
|
|
208
|
+
#
|
|
209
|
+
# @param [ Criteria ] criteria The criteria.
|
|
210
|
+
#
|
|
211
|
+
# @since 3.0.0
|
|
212
|
+
def initialize(criteria)
|
|
213
|
+
@criteria, @klass, @cache = criteria, criteria.klass, criteria.options[:cache]
|
|
214
|
+
add_type_selection
|
|
215
|
+
@query = klass.collection.find(criteria.selector)
|
|
216
|
+
apply_options
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Get the last document in the database for the criteria's selector.
|
|
220
|
+
#
|
|
221
|
+
# @example Get the last document.
|
|
222
|
+
# context.last
|
|
223
|
+
#
|
|
224
|
+
# @return [ Document ] The last document.
|
|
225
|
+
#
|
|
226
|
+
# @since 3.0.0
|
|
227
|
+
def last
|
|
228
|
+
apply_inverse_sorting
|
|
229
|
+
with_eager_loading(query.first)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# Get's the number of documents matching the query selector.
|
|
233
|
+
#
|
|
234
|
+
# @example Get the length.
|
|
235
|
+
# context.length
|
|
236
|
+
#
|
|
237
|
+
# @return [ Integer ] The number of documents.
|
|
238
|
+
#
|
|
239
|
+
# @since 3.0.0
|
|
240
|
+
def length
|
|
241
|
+
@length ||= query.count
|
|
242
|
+
end
|
|
243
|
+
alias :size :length
|
|
244
|
+
|
|
245
|
+
# Limits the number of documents that are returned from the database.
|
|
246
|
+
#
|
|
247
|
+
# @example Limit the documents.
|
|
248
|
+
# context.limit(20)
|
|
249
|
+
#
|
|
250
|
+
# @param [ Integer ] value The number of documents to return.
|
|
251
|
+
#
|
|
252
|
+
# @return [ Mongo ] The context.
|
|
253
|
+
#
|
|
254
|
+
# @since 3.0.0
|
|
255
|
+
def limit(value)
|
|
256
|
+
query.limit(value) and self
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Initiate a map/reduce operation from the context.
|
|
260
|
+
#
|
|
261
|
+
# @example Initiate a map/reduce.
|
|
262
|
+
# context.map_reduce(map, reduce)
|
|
263
|
+
#
|
|
264
|
+
# @param [ String ] map The map js function.
|
|
265
|
+
# @param [ String ] reduce The reduce js function.
|
|
266
|
+
#
|
|
267
|
+
# @return [ MapReduce ] The map/reduce lazy wrapper.
|
|
268
|
+
#
|
|
269
|
+
# @since 3.0.0
|
|
270
|
+
def map_reduce(map, reduce)
|
|
271
|
+
MapReduce.new(criteria, map, reduce)
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
# Skips the provided number of documents.
|
|
275
|
+
#
|
|
276
|
+
# @example Skip the documents.
|
|
277
|
+
# context.skip(20)
|
|
278
|
+
#
|
|
279
|
+
# @param [ Integer ] value The number of documents to skip.
|
|
280
|
+
#
|
|
281
|
+
# @return [ Mongo ] The context.
|
|
282
|
+
#
|
|
283
|
+
# @since 3.0.0
|
|
284
|
+
def skip(value)
|
|
285
|
+
query.skip(value) and self
|
|
286
|
+
end
|
|
287
|
+
|
|
288
|
+
# Sorts the documents by the provided spec.
|
|
289
|
+
#
|
|
290
|
+
# @example Sort the documents.
|
|
291
|
+
# context.sort(name: -1, title: 1)
|
|
292
|
+
#
|
|
293
|
+
# @param [ Hash ] values The sorting values as field/direction(1/-1)
|
|
294
|
+
# pairs.
|
|
295
|
+
#
|
|
296
|
+
# @return [ Mongo ] The context.
|
|
297
|
+
#
|
|
298
|
+
# @since 3.0.0
|
|
299
|
+
def sort(values = nil, &block)
|
|
300
|
+
if block_given?
|
|
301
|
+
super(&block)
|
|
302
|
+
else
|
|
303
|
+
query.sort(values) and self
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# Update all the matching documents atomically.
|
|
308
|
+
#
|
|
309
|
+
# @example Update all the matching documents.
|
|
310
|
+
# context.update({ "$set" => { name: "Smiths" }})
|
|
311
|
+
#
|
|
312
|
+
# @param [ Hash ] attributes The new attributes for each document.
|
|
313
|
+
#
|
|
314
|
+
# @return [ nil, false ] False if no attributes were provided.
|
|
315
|
+
#
|
|
316
|
+
# @since 3.0.0
|
|
317
|
+
def update(attributes = nil)
|
|
318
|
+
return false unless attributes
|
|
319
|
+
query.update_all(attributes.__consolidate__)
|
|
320
|
+
end
|
|
321
|
+
alias :update_all :update
|
|
322
|
+
|
|
323
|
+
private
|
|
324
|
+
|
|
325
|
+
# For models where inheritance is at play we need to add the type
|
|
326
|
+
# selection.
|
|
327
|
+
#
|
|
328
|
+
# @example Add the type selection.
|
|
329
|
+
# context.add_type_selection
|
|
330
|
+
#
|
|
331
|
+
# @return [ true, false ] If type selection was added.
|
|
332
|
+
#
|
|
333
|
+
# @since 3.0.0
|
|
334
|
+
def add_type_selection
|
|
335
|
+
if klass.hereditary? && !criteria.selector.keys.include?(:_type)
|
|
336
|
+
criteria.selector.merge!(_type: { "$in" => klass._types })
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
|
|
340
|
+
# Apply the field limitations.
|
|
341
|
+
#
|
|
342
|
+
# @api private
|
|
343
|
+
#
|
|
344
|
+
# @example Apply the field limitations.
|
|
345
|
+
# context.apply_fields
|
|
346
|
+
#
|
|
347
|
+
# @since 3.0.0
|
|
348
|
+
def apply_fields
|
|
349
|
+
if spec = criteria.options[:fields]
|
|
350
|
+
query.select(spec)
|
|
351
|
+
end
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
# Apply the skip option.
|
|
355
|
+
#
|
|
356
|
+
# @api private
|
|
357
|
+
#
|
|
358
|
+
# @example Apply the skip option.
|
|
359
|
+
# context.apply_skip
|
|
360
|
+
#
|
|
361
|
+
# @since 3.0.0
|
|
362
|
+
def apply_skip
|
|
363
|
+
if spec = criteria.options[:skip]
|
|
364
|
+
query.skip(spec)
|
|
365
|
+
end
|
|
366
|
+
end
|
|
367
|
+
|
|
368
|
+
# Apply the limit option.
|
|
369
|
+
#
|
|
370
|
+
# @api private
|
|
371
|
+
#
|
|
372
|
+
# @example Apply the limit option.
|
|
373
|
+
# context.apply_limit
|
|
374
|
+
#
|
|
375
|
+
# @since 3.0.0
|
|
376
|
+
def apply_limit
|
|
377
|
+
if spec = criteria.options[:limit]
|
|
378
|
+
query.limit(spec)
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
# Map the sort symbols to the correct MongoDB values.
|
|
383
|
+
#
|
|
384
|
+
# @example Apply the sorting params.
|
|
385
|
+
# context.apply_sorting
|
|
386
|
+
#
|
|
387
|
+
# @since 3.0.0
|
|
388
|
+
def apply_sorting
|
|
389
|
+
if spec = criteria.options[:sort]
|
|
390
|
+
query.sort(spec)
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
|
|
394
|
+
# Apply the hint option
|
|
395
|
+
#
|
|
396
|
+
# @example Apply the hint params.
|
|
397
|
+
# context.apply_hint
|
|
398
|
+
#
|
|
399
|
+
# @since 3.0.0
|
|
400
|
+
def apply_hint
|
|
401
|
+
if spec = criteria.options[:hint]
|
|
402
|
+
query.hint(spec)
|
|
403
|
+
end
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
# Map the inverse sort symbols to the correct MongoDB values.
|
|
407
|
+
#
|
|
408
|
+
# @example Apply the inverse sorting params.
|
|
409
|
+
# context.apply_inverse_sorting
|
|
410
|
+
#
|
|
411
|
+
# @since 3.0.0
|
|
412
|
+
def apply_inverse_sorting
|
|
413
|
+
if spec = criteria.options[:sort]
|
|
414
|
+
query.sort(Hash[spec.map{|k, v| [k, -1*v]}])
|
|
415
|
+
else
|
|
416
|
+
query.sort({_id: -1})
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
|
|
420
|
+
# Is the cache able to be added to?
|
|
421
|
+
#
|
|
422
|
+
# @api private
|
|
423
|
+
#
|
|
424
|
+
# @example Is the context cacheable?
|
|
425
|
+
# context.cacheable?
|
|
426
|
+
#
|
|
427
|
+
# @return [ true, false ] If caching, and the cache isn't loaded.
|
|
428
|
+
#
|
|
429
|
+
# @since 3.0.0
|
|
430
|
+
def cacheable?
|
|
431
|
+
cached? && !cache_loaded?
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
# Is the cache fully loaded? Will be true if caching after one full
|
|
435
|
+
# iteration.
|
|
436
|
+
#
|
|
437
|
+
# @api private
|
|
438
|
+
#
|
|
439
|
+
# @example Is the cache loaded?
|
|
440
|
+
# context.cache_loaded?
|
|
441
|
+
#
|
|
442
|
+
# @return [ true, false ] If the cache is loaded.
|
|
443
|
+
#
|
|
444
|
+
# @since 3.0.0
|
|
445
|
+
def cache_loaded?
|
|
446
|
+
!!@cache_loaded
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
# Get the documents for cached queries.
|
|
450
|
+
#
|
|
451
|
+
# @api private
|
|
452
|
+
#
|
|
453
|
+
# @example Get the cached documents.
|
|
454
|
+
# context.documents
|
|
455
|
+
#
|
|
456
|
+
# @return [ Array<Document> ] The documents.
|
|
457
|
+
#
|
|
458
|
+
# @since 3.0.0
|
|
459
|
+
def documents
|
|
460
|
+
@documents ||= []
|
|
461
|
+
end
|
|
462
|
+
|
|
463
|
+
# Get the documents the context should iterate. This follows 3 rules:
|
|
464
|
+
#
|
|
465
|
+
# 1. If the query is cached, and we already have documents loaded, use
|
|
466
|
+
# them.
|
|
467
|
+
# 2. If we are eager loading, then eager load the documents and use
|
|
468
|
+
# those.
|
|
469
|
+
# 3. Use the query.
|
|
470
|
+
#
|
|
471
|
+
# @api private
|
|
472
|
+
#
|
|
473
|
+
# @example Get the documents for iteration.
|
|
474
|
+
# context.documents_for_iteration
|
|
475
|
+
#
|
|
476
|
+
# @return [ Array<Document>, Moped::Query ] The docs to iterate.
|
|
477
|
+
#
|
|
478
|
+
# @since 3.0.0
|
|
479
|
+
def documents_for_iteration
|
|
480
|
+
if cached? && !documents.empty?
|
|
481
|
+
documents
|
|
482
|
+
elsif eager_loadable?
|
|
483
|
+
docs = query.map{ |doc| Factory.from_db(klass, doc) }
|
|
484
|
+
eager_load(docs)
|
|
485
|
+
docs
|
|
486
|
+
else
|
|
487
|
+
query
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
# Eager load the inclusions for the provided documents.
|
|
492
|
+
#
|
|
493
|
+
# @example Eager load the inclusions.
|
|
494
|
+
# context.eager_load(docs)
|
|
495
|
+
#
|
|
496
|
+
# @param [ Array<Document> ] docs The docs returning from the db.
|
|
497
|
+
#
|
|
498
|
+
# @return [ true ] Always true.
|
|
499
|
+
#
|
|
500
|
+
# @since 3.0.0
|
|
501
|
+
def eager_load(docs)
|
|
502
|
+
criteria.inclusions.reject! do |metadata|
|
|
503
|
+
metadata.eager_load(eager_loaded_ids(docs, metadata)) if !docs.empty?
|
|
504
|
+
end
|
|
505
|
+
self.eager_loaded = true
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
# Get the ids that to be used to eager load documents.
|
|
509
|
+
#
|
|
510
|
+
# @api private
|
|
511
|
+
#
|
|
512
|
+
# @example Get the ids.
|
|
513
|
+
# context.eager_load(docs, metadata)
|
|
514
|
+
#
|
|
515
|
+
# @param [ Array<Document> ] docs The pre-loaded documents.
|
|
516
|
+
# @param [ Metadata ] metadata The relation metadata.
|
|
517
|
+
#
|
|
518
|
+
# @return [ Array<Object> ] The ids.
|
|
519
|
+
#
|
|
520
|
+
# @since 3.0.0
|
|
521
|
+
def eager_loaded_ids(docs, metadata)
|
|
522
|
+
if metadata.stores_foreign_key?
|
|
523
|
+
load_ids(metadata.foreign_key).flatten
|
|
524
|
+
else
|
|
525
|
+
docs.map(&:id)
|
|
526
|
+
end
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
# Is this context able to be eager loaded?
|
|
530
|
+
#
|
|
531
|
+
# @example Is the context eager loadable?
|
|
532
|
+
# context.eager_loadable?
|
|
533
|
+
#
|
|
534
|
+
# @return [ true, false ] If the context is able to be eager loaded.
|
|
535
|
+
#
|
|
536
|
+
# @since 3.0.0
|
|
537
|
+
def eager_loadable?
|
|
538
|
+
!eager_loaded && !criteria.inclusions.empty?
|
|
539
|
+
end
|
|
540
|
+
|
|
541
|
+
# Increment the length of the results.
|
|
542
|
+
#
|
|
543
|
+
# @api private
|
|
544
|
+
#
|
|
545
|
+
# @example Increment the length.
|
|
546
|
+
# context.increment_length
|
|
547
|
+
#
|
|
548
|
+
# @return [ Integer ] The new length
|
|
549
|
+
#
|
|
550
|
+
# @since 3.0.0
|
|
551
|
+
def increment_length
|
|
552
|
+
@length += 1
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
# Reset the length to zero. This happens once before iteration.
|
|
556
|
+
#
|
|
557
|
+
# @api private
|
|
558
|
+
#
|
|
559
|
+
# @example Reset the length.
|
|
560
|
+
# context.reset_length
|
|
561
|
+
#
|
|
562
|
+
# @return [ Integer ] zero.
|
|
563
|
+
#
|
|
564
|
+
# @since 3.0.0
|
|
565
|
+
def reset_length
|
|
566
|
+
@length = 0
|
|
567
|
+
end
|
|
568
|
+
|
|
569
|
+
# Loads an array of ids only for the current criteria. Used by eager
|
|
570
|
+
# loading to determine the documents to load.
|
|
571
|
+
#
|
|
572
|
+
# @example Load the related ids.
|
|
573
|
+
# criteria.load_ids("person_id")
|
|
574
|
+
#
|
|
575
|
+
# @param [ String ] key The id or foriegn key string.
|
|
576
|
+
#
|
|
577
|
+
# @return [ Array<String, Moped::BSON::ObjectId> ] The ids to load.
|
|
578
|
+
#
|
|
579
|
+
# @since 3.0.0
|
|
580
|
+
def load_ids(key)
|
|
581
|
+
query.select(key => 1).map do |doc|
|
|
582
|
+
doc[key]
|
|
583
|
+
end
|
|
584
|
+
end
|
|
585
|
+
|
|
586
|
+
# Apply all the optional criterion.
|
|
587
|
+
#
|
|
588
|
+
# @example Apply the options.
|
|
589
|
+
# context.apply_options
|
|
590
|
+
#
|
|
591
|
+
# @since 3.0.0
|
|
592
|
+
def apply_options
|
|
593
|
+
apply_fields
|
|
594
|
+
apply_limit
|
|
595
|
+
apply_skip
|
|
596
|
+
apply_sorting
|
|
597
|
+
apply_hint
|
|
598
|
+
end
|
|
599
|
+
|
|
600
|
+
# If we are limiting results, we need to set the field limitations on a
|
|
601
|
+
# thread local to avoid overriding the default values.
|
|
602
|
+
#
|
|
603
|
+
# @example Execute with selection.
|
|
604
|
+
# context.selecting do
|
|
605
|
+
# collection.find
|
|
606
|
+
# end
|
|
607
|
+
#
|
|
608
|
+
# @return [ Object ] The yielded value.
|
|
609
|
+
#
|
|
610
|
+
# @since 2.4.4
|
|
611
|
+
def selecting
|
|
612
|
+
begin
|
|
613
|
+
unless criteria.options[:fields].blank?
|
|
614
|
+
Threaded.selection = criteria.options[:fields]
|
|
615
|
+
end
|
|
616
|
+
yield
|
|
617
|
+
ensure
|
|
618
|
+
Threaded.selection = nil
|
|
619
|
+
end
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
# If the provided document exists, eager load it's dependencies or return
|
|
623
|
+
# nil.
|
|
624
|
+
#
|
|
625
|
+
# @example Eager load if the document is not nil.
|
|
626
|
+
# context.with_eager_loading(document)
|
|
627
|
+
#
|
|
628
|
+
# @param [ Hash ] document The document from the database.
|
|
629
|
+
#
|
|
630
|
+
# @return [ Document, nil ] The instantiated model document.
|
|
631
|
+
#
|
|
632
|
+
# @since 3.0.0
|
|
633
|
+
def with_eager_loading(document)
|
|
634
|
+
selecting do
|
|
635
|
+
return nil unless document
|
|
636
|
+
doc = Factory.from_db(klass, document)
|
|
637
|
+
eager_load([ doc ]) if eager_loadable?
|
|
638
|
+
doc
|
|
639
|
+
end
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
# Yield to the document and increment the length.
|
|
643
|
+
#
|
|
644
|
+
# @api private
|
|
645
|
+
#
|
|
646
|
+
# @example Yield and increment.
|
|
647
|
+
# context.yield_and_increment(doc) do |doc|
|
|
648
|
+
# ...
|
|
649
|
+
# end
|
|
650
|
+
#
|
|
651
|
+
# @param [ Document ] document The document to yield to.
|
|
652
|
+
#
|
|
653
|
+
# @since 3.0.0
|
|
654
|
+
def yield_and_increment(document, &block)
|
|
655
|
+
doc = document.respond_to?(:_id) ? document : Factory.from_db(klass, document)
|
|
656
|
+
yield(doc)
|
|
657
|
+
increment_length
|
|
658
|
+
documents.push(doc) if cacheable?
|
|
659
|
+
end
|
|
660
|
+
end
|
|
661
|
+
end
|
|
662
|
+
end
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/contextual/memory"
|
|
3
|
+
require "mongoid/contextual/mongo"
|
|
4
|
+
|
|
5
|
+
module Mongoid
|
|
6
|
+
module Contextual
|
|
7
|
+
|
|
8
|
+
# The aggregate operations provided in the aggregate module get delegated
|
|
9
|
+
# through to the context from the criteria.
|
|
10
|
+
delegate(*Aggregable::Mongo.public_instance_methods(false), to: :context)
|
|
11
|
+
|
|
12
|
+
# The atomic operations provided in the atomic context get delegated
|
|
13
|
+
# through to the context from the criteria.
|
|
14
|
+
delegate(*Atomic.public_instance_methods(false), to: :context)
|
|
15
|
+
|
|
16
|
+
# The methods in the contexts themselves should all get delegated to,
|
|
17
|
+
# including destructive, modification, and optional methods.
|
|
18
|
+
delegate(*(Mongo.public_instance_methods(false) - [ :skip, :limit ]), to: :context)
|
|
19
|
+
|
|
20
|
+
# Get the context in which criteria queries should execute. This is either
|
|
21
|
+
# in memory (for embedded documents) or mongo (for root level documents.)
|
|
22
|
+
#
|
|
23
|
+
# @example Get the context.
|
|
24
|
+
# criteria.context
|
|
25
|
+
#
|
|
26
|
+
# @return [ Memory, Mongo ] The context.
|
|
27
|
+
#
|
|
28
|
+
# @since 3.0.0
|
|
29
|
+
def context
|
|
30
|
+
@context ||= create_context
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
# Create the context for the queries to execute. Will be memory for
|
|
36
|
+
# embedded documents and mongo for root documents.
|
|
37
|
+
#
|
|
38
|
+
# @api private
|
|
39
|
+
#
|
|
40
|
+
# @example Create the context.
|
|
41
|
+
# contextual.create_context
|
|
42
|
+
#
|
|
43
|
+
# @return [ Mongo, Memory ] The context.
|
|
44
|
+
#
|
|
45
|
+
# @since 3.0.0
|
|
46
|
+
def create_context
|
|
47
|
+
embedded ? Memory.new(self) : Mongo.new(self)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|