mongoid 7.2.1 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +20 -20
- data/LICENSE +1 -1
- data/README.md +7 -12
- data/Rakefile +58 -1
- data/lib/config/locales/en.yml +191 -60
- data/lib/mongoid/association/accessors.rb +67 -53
- data/lib/mongoid/association/bindable.rb +77 -31
- data/lib/mongoid/association/builders.rb +8 -14
- data/lib/mongoid/association/constrainable.rb +2 -5
- data/lib/mongoid/association/depending.rb +20 -12
- data/lib/mongoid/association/eager.rb +160 -0
- data/lib/mongoid/association/eager_loadable.rb +41 -11
- data/lib/mongoid/association/embedded/batchable.rb +63 -52
- data/lib/mongoid/association/embedded/cyclic.rb +4 -12
- data/lib/mongoid/association/embedded/eager.rb +23 -0
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +29 -13
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +3 -5
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +25 -23
- data/lib/mongoid/association/embedded/embedded_in.rb +11 -26
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +4 -9
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +5 -6
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +226 -203
- data/lib/mongoid/association/embedded/embeds_many.rb +3 -33
- data/lib/mongoid/association/embedded/embeds_one/binding.rb +3 -9
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +20 -8
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +131 -42
- data/lib/mongoid/association/embedded/embeds_one.rb +4 -30
- data/lib/mongoid/association/embedded.rb +2 -1
- data/lib/mongoid/association/macros.rb +47 -16
- data/lib/mongoid/association/many.rb +12 -24
- data/lib/mongoid/association/marshalable.rb +4 -5
- data/lib/mongoid/association/nested/many.rb +14 -19
- data/lib/mongoid/association/nested/nested_buildable.rb +36 -13
- data/lib/mongoid/association/nested/one.rb +54 -26
- data/lib/mongoid/association/nested.rb +1 -3
- data/lib/mongoid/association/one.rb +3 -11
- data/lib/mongoid/association/options.rb +18 -44
- data/lib/mongoid/association/proxy.rb +49 -42
- data/lib/mongoid/association/referenced/auto_save.rb +11 -15
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +2 -7
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +6 -6
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +2 -2
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +23 -32
- data/lib/mongoid/association/referenced/belongs_to.rb +13 -37
- data/lib/mongoid/association/referenced/counter_cache.rb +18 -26
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +15 -8
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +1 -3
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +191 -123
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +23 -42
- data/lib/mongoid/association/referenced/has_many/binding.rb +1 -5
- data/lib/mongoid/association/referenced/has_many/buildable.rb +1 -3
- data/lib/mongoid/association/referenced/has_many/eager.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +471 -496
- data/lib/mongoid/association/referenced/has_many/proxy.rb +182 -179
- data/lib/mongoid/association/referenced/has_many.rb +17 -43
- data/lib/mongoid/association/referenced/has_one/binding.rb +1 -7
- data/lib/mongoid/association/referenced/has_one/buildable.rb +5 -5
- data/lib/mongoid/association/referenced/has_one/eager.rb +3 -4
- data/lib/mongoid/association/referenced/has_one/proxy.rb +38 -41
- data/lib/mongoid/association/referenced/has_one.rb +17 -36
- data/lib/mongoid/association/referenced/syncable.rb +11 -27
- data/lib/mongoid/association/referenced.rb +1 -1
- data/lib/mongoid/association/reflections.rb +9 -9
- data/lib/mongoid/association/relatable.rb +55 -74
- data/lib/mongoid/association.rb +10 -22
- data/lib/mongoid/atomic/modifiers.rb +7 -53
- data/lib/mongoid/atomic/paths/embedded/many.rb +20 -5
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -5
- data/lib/mongoid/atomic/paths/embedded.rb +1 -3
- data/lib/mongoid/atomic/paths/root.rb +1 -5
- data/lib/mongoid/atomic/paths.rb +1 -1
- data/lib/mongoid/atomic.rb +39 -86
- data/lib/mongoid/atomic_update_preparer.rb +88 -0
- data/lib/mongoid/attributes/dynamic.rb +5 -21
- data/lib/mongoid/attributes/embedded.rb +34 -0
- data/lib/mongoid/attributes/nested.rb +9 -13
- data/lib/mongoid/attributes/processing.rb +43 -28
- data/lib/mongoid/attributes/projector.rb +120 -0
- data/lib/mongoid/attributes/readonly.rb +4 -8
- data/lib/mongoid/attributes.rb +85 -89
- data/lib/mongoid/cacheable.rb +5 -9
- data/lib/mongoid/changeable.rb +183 -97
- data/lib/mongoid/clients/factory.rb +58 -15
- data/lib/mongoid/clients/options.rb +117 -8
- data/lib/mongoid/clients/sessions.rb +246 -84
- data/lib/mongoid/clients/storage_options.rb +37 -11
- data/lib/mongoid/clients/validators/storage.rb +4 -24
- data/lib/mongoid/clients/validators.rb +1 -1
- data/lib/mongoid/clients.rb +37 -14
- data/lib/mongoid/collection_configurable.rb +59 -0
- data/lib/mongoid/composable.rb +7 -7
- data/lib/mongoid/config/defaults.rb +40 -0
- data/lib/mongoid/config/encryption.rb +213 -0
- data/lib/mongoid/config/environment.rb +25 -5
- data/lib/mongoid/config/introspection.rb +152 -0
- data/lib/mongoid/config/options.rb +11 -14
- data/lib/mongoid/config/validators/async_query_executor.rb +34 -0
- data/lib/mongoid/config/validators/client.rb +7 -23
- data/lib/mongoid/config/validators/option.rb +1 -3
- data/lib/mongoid/config/validators.rb +2 -1
- data/lib/mongoid/config.rb +183 -46
- data/lib/mongoid/contextual/aggregable/memory.rb +38 -26
- data/lib/mongoid/contextual/aggregable/mongo.rb +26 -32
- data/lib/mongoid/contextual/aggregable/none.rb +66 -0
- data/lib/mongoid/contextual/aggregable.rb +18 -0
- data/lib/mongoid/contextual/atomic.rb +97 -30
- data/lib/mongoid/contextual/command.rb +3 -5
- data/lib/mongoid/contextual/map_reduce.rb +8 -33
- data/lib/mongoid/contextual/memory.rb +396 -89
- data/lib/mongoid/contextual/mongo/documents_loader.rb +178 -0
- data/lib/mongoid/contextual/mongo.rb +640 -311
- data/lib/mongoid/contextual/none.rb +244 -30
- data/lib/mongoid/contextual/queryable.rb +5 -4
- data/lib/mongoid/contextual.rb +18 -7
- data/lib/mongoid/copyable.rb +34 -14
- data/lib/mongoid/criteria/findable.rb +52 -22
- data/lib/mongoid/criteria/includable.rb +31 -34
- data/lib/mongoid/criteria/inspectable.rb +4 -3
- data/lib/mongoid/criteria/marshalable.rb +14 -7
- data/lib/mongoid/criteria/modifiable.rb +5 -19
- data/lib/mongoid/criteria/options.rb +1 -3
- data/lib/mongoid/criteria/permission.rb +6 -2
- data/lib/mongoid/criteria/queryable/aggregable.rb +3 -15
- data/lib/mongoid/criteria/queryable/expandable.rb +1 -25
- data/lib/mongoid/criteria/queryable/extensions/array.rb +6 -41
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -9
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +5 -7
- data/lib/mongoid/criteria/queryable/extensions/date.rb +10 -11
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +8 -7
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +3 -41
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +2 -14
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +3 -21
- data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -30
- data/lib/mongoid/criteria/queryable/extensions/range.rb +48 -17
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -13
- data/lib/mongoid/criteria/queryable/extensions/set.rb +3 -5
- data/lib/mongoid/criteria/queryable/extensions/string.rb +19 -34
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +6 -22
- data/lib/mongoid/criteria/queryable/extensions/time.rb +8 -9
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +9 -9
- data/lib/mongoid/criteria/queryable/extensions.rb +1 -5
- data/lib/mongoid/criteria/queryable/key.rb +15 -18
- data/lib/mongoid/criteria/queryable/macroable.rb +1 -3
- data/lib/mongoid/criteria/queryable/mergeable.rb +69 -50
- data/lib/mongoid/criteria/queryable/optional.rb +12 -62
- data/lib/mongoid/criteria/queryable/options.rb +3 -21
- data/lib/mongoid/criteria/queryable/pipeline.rb +2 -14
- data/lib/mongoid/criteria/queryable/selectable.rb +87 -124
- data/lib/mongoid/criteria/queryable/selector.rb +96 -25
- data/lib/mongoid/criteria/queryable/smash.rb +41 -18
- data/lib/mongoid/criteria/queryable/storable.rb +14 -9
- data/lib/mongoid/criteria/queryable.rb +12 -13
- data/lib/mongoid/criteria/scopable.rb +32 -21
- data/lib/mongoid/criteria/translator.rb +46 -0
- data/lib/mongoid/criteria.rb +60 -109
- data/lib/mongoid/deprecable.rb +38 -0
- data/lib/mongoid/deprecation.rb +29 -0
- data/lib/mongoid/document.rb +263 -173
- data/lib/mongoid/encryptable.rb +53 -0
- data/lib/mongoid/equality.rb +22 -25
- data/lib/mongoid/errors/ambiguous_relationship.rb +3 -5
- data/lib/mongoid/errors/attribute_not_loaded.rb +34 -0
- data/lib/mongoid/errors/callback.rb +1 -3
- data/lib/mongoid/errors/create_collection_failure.rb +34 -0
- data/lib/mongoid/errors/criteria_argument_required.rb +1 -1
- data/lib/mongoid/errors/delete_restriction.rb +9 -12
- data/lib/mongoid/errors/document_not_destroyed.rb +3 -7
- data/lib/mongoid/errors/document_not_found.rb +34 -21
- data/lib/mongoid/errors/drop_collection_failure.rb +28 -0
- data/lib/mongoid/errors/empty_config_file.rb +26 -0
- data/lib/mongoid/errors/immutable_attribute.rb +27 -0
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -3
- data/lib/mongoid/errors/invalid_async_query_executor.rb +26 -0
- data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +33 -0
- data/lib/mongoid/errors/invalid_collection.rb +1 -1
- data/lib/mongoid/errors/invalid_config_file.rb +26 -0
- data/lib/mongoid/errors/invalid_config_option.rb +2 -4
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +2 -4
- data/lib/mongoid/errors/invalid_discriminator_key_target.rb +1 -1
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +24 -0
- data/lib/mongoid/errors/invalid_elem_match_operator.rb +1 -1
- data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +6 -5
- data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +27 -0
- data/lib/mongoid/errors/invalid_expression_operator.rb +1 -1
- data/lib/mongoid/errors/invalid_field.rb +7 -7
- data/lib/mongoid/errors/invalid_field_operator.rb +1 -1
- data/lib/mongoid/errors/invalid_field_option.rb +1 -3
- data/lib/mongoid/errors/invalid_field_type.rb +27 -0
- data/lib/mongoid/errors/invalid_find.rb +1 -3
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +23 -0
- data/lib/mongoid/errors/invalid_includes.rb +1 -3
- data/lib/mongoid/errors/invalid_index.rb +1 -3
- data/lib/mongoid/errors/invalid_options.rb +1 -3
- data/lib/mongoid/errors/invalid_path.rb +1 -3
- data/lib/mongoid/errors/invalid_persistence_option.rb +1 -5
- data/lib/mongoid/errors/invalid_query.rb +1 -1
- data/lib/mongoid/errors/invalid_relation.rb +2 -8
- data/lib/mongoid/errors/invalid_relation_option.rb +2 -4
- data/lib/mongoid/errors/invalid_scope.rb +1 -3
- data/lib/mongoid/errors/invalid_session_nesting.rb +17 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +1 -2
- data/lib/mongoid/errors/invalid_storage_options.rb +2 -4
- data/lib/mongoid/errors/invalid_time.rb +1 -3
- data/lib/mongoid/errors/invalid_transaction_nesting.rb +17 -0
- data/lib/mongoid/errors/inverse_not_found.rb +1 -3
- data/lib/mongoid/errors/mixed_client_configuration.rb +1 -3
- data/lib/mongoid/errors/mixed_relations.rb +1 -3
- data/lib/mongoid/errors/mongoid_error.rb +8 -16
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +2 -4
- data/lib/mongoid/errors/no_client_config.rb +1 -3
- data/lib/mongoid/errors/no_client_database.rb +2 -4
- data/lib/mongoid/errors/no_client_hosts.rb +2 -4
- data/lib/mongoid/errors/no_clients_config.rb +1 -3
- data/lib/mongoid/errors/no_default_client.rb +1 -3
- data/lib/mongoid/errors/no_environment.rb +1 -3
- data/lib/mongoid/errors/no_map_reduce_output.rb +1 -3
- data/lib/mongoid/errors/no_metadata.rb +1 -3
- data/lib/mongoid/errors/no_parent.rb +1 -3
- data/lib/mongoid/errors/readonly_attribute.rb +2 -4
- data/lib/mongoid/errors/readonly_document.rb +2 -6
- data/lib/mongoid/errors/rollback.rb +15 -0
- data/lib/mongoid/errors/scope_overwrite.rb +1 -1
- data/lib/mongoid/errors/sessions_not_supported.rb +17 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +2 -2
- data/lib/mongoid/errors/transaction_error.rb +25 -0
- data/lib/mongoid/errors/transactions_not_supported.rb +17 -0
- data/lib/mongoid/errors/unknown_attribute.rb +2 -4
- data/lib/mongoid/errors/unknown_model.rb +1 -3
- data/lib/mongoid/errors/unsaved_document.rb +2 -2
- data/lib/mongoid/errors/unsupported_javascript.rb +1 -3
- data/lib/mongoid/errors/validations.rb +1 -1
- data/lib/mongoid/errors.rb +18 -5
- data/lib/mongoid/evolvable.rb +2 -4
- data/lib/mongoid/extensions/array.rb +20 -58
- data/lib/mongoid/extensions/big_decimal.rb +44 -24
- data/lib/mongoid/extensions/binary.rb +45 -0
- data/lib/mongoid/extensions/boolean.rb +11 -6
- data/lib/mongoid/extensions/date.rb +31 -29
- data/lib/mongoid/extensions/date_time.rb +5 -16
- data/lib/mongoid/extensions/decimal128.rb +3 -5
- data/lib/mongoid/extensions/false_class.rb +8 -10
- data/lib/mongoid/extensions/float.rb +11 -12
- data/lib/mongoid/extensions/hash.rb +28 -148
- data/lib/mongoid/extensions/integer.rb +13 -14
- data/lib/mongoid/extensions/module.rb +5 -5
- data/lib/mongoid/extensions/nil_class.rb +5 -7
- data/lib/mongoid/extensions/object.rb +32 -81
- data/lib/mongoid/extensions/object_id.rb +3 -7
- data/lib/mongoid/extensions/range.rb +47 -24
- data/lib/mongoid/extensions/raw_value.rb +34 -0
- data/lib/mongoid/extensions/regexp.rb +14 -7
- data/lib/mongoid/extensions/set.rb +24 -13
- data/lib/mongoid/extensions/string.rb +30 -62
- data/lib/mongoid/extensions/symbol.rb +9 -22
- data/lib/mongoid/extensions/time.rb +30 -40
- data/lib/mongoid/extensions/time_with_zone.rb +18 -11
- data/lib/mongoid/extensions/true_class.rb +8 -10
- data/lib/mongoid/extensions.rb +3 -20
- data/lib/mongoid/factory.rb +178 -37
- data/lib/mongoid/fields/encrypted.rb +48 -0
- data/lib/mongoid/fields/foreign_key.rb +39 -27
- data/lib/mongoid/fields/localized.rb +25 -15
- data/lib/mongoid/fields/standard.rb +22 -40
- data/lib/mongoid/fields/validators/macro.rb +6 -19
- data/lib/mongoid/fields/validators.rb +1 -1
- data/lib/mongoid/fields.rb +354 -76
- data/lib/mongoid/findable.rb +62 -22
- data/lib/mongoid/indexable/specification.rb +55 -34
- data/lib/mongoid/indexable/validators/options.rb +7 -9
- data/lib/mongoid/indexable.rb +2 -18
- data/lib/mongoid/inspectable.rb +34 -11
- data/lib/mongoid/interceptable.rb +197 -41
- data/lib/mongoid/loadable.rb +83 -0
- data/lib/mongoid/loggable.rb +1 -9
- data/lib/mongoid/matchable.rb +2 -6
- data/lib/mongoid/matcher/all.rb +15 -0
- data/lib/mongoid/matcher/and.rb +14 -0
- data/lib/mongoid/matcher/bits.rb +60 -0
- data/lib/mongoid/matcher/bits_all_clear.rb +41 -0
- data/lib/mongoid/matcher/bits_all_set.rb +41 -0
- data/lib/mongoid/matcher/bits_any_clear.rb +41 -0
- data/lib/mongoid/matcher/bits_any_set.rb +41 -0
- data/lib/mongoid/matcher/elem_match.rb +17 -1
- data/lib/mongoid/matcher/elem_match_expression.rb +14 -2
- data/lib/mongoid/matcher/eq.rb +15 -0
- data/lib/mongoid/matcher/eq_impl.rb +54 -2
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +18 -1
- data/lib/mongoid/matcher/exists.rb +15 -0
- data/lib/mongoid/matcher/expression.rb +22 -14
- data/lib/mongoid/matcher/expression_operator.rb +14 -0
- data/lib/mongoid/matcher/field_expression.rb +19 -5
- data/lib/mongoid/matcher/field_operator.rb +30 -0
- data/lib/mongoid/matcher/gt.rb +15 -0
- data/lib/mongoid/matcher/gte.rb +15 -0
- data/lib/mongoid/matcher/in.rb +15 -0
- data/lib/mongoid/matcher/lt.rb +15 -0
- data/lib/mongoid/matcher/lte.rb +15 -0
- data/lib/mongoid/matcher/mod.rb +33 -0
- data/lib/mongoid/matcher/ne.rb +15 -0
- data/lib/mongoid/matcher/nin.rb +15 -0
- data/lib/mongoid/matcher/nor.rb +14 -0
- data/lib/mongoid/matcher/not.rb +16 -0
- data/lib/mongoid/matcher/or.rb +14 -0
- data/lib/mongoid/matcher/regex.rb +24 -0
- data/lib/mongoid/matcher/size.rb +16 -0
- data/lib/mongoid/matcher/type.rb +124 -0
- data/lib/mongoid/matcher.rb +59 -52
- data/lib/mongoid/persistable/creatable.rb +25 -29
- data/lib/mongoid/persistable/deletable.rb +10 -23
- data/lib/mongoid/persistable/destroyable.rb +37 -11
- data/lib/mongoid/persistable/incrementable.rb +2 -6
- data/lib/mongoid/persistable/logical.rb +1 -5
- data/lib/mongoid/persistable/maxable.rb +37 -0
- data/lib/mongoid/persistable/minable.rb +37 -0
- data/lib/mongoid/persistable/multipliable.rb +36 -0
- data/lib/mongoid/persistable/poppable.rb +1 -5
- data/lib/mongoid/persistable/pullable.rb +1 -7
- data/lib/mongoid/persistable/pushable.rb +1 -7
- data/lib/mongoid/persistable/renamable.rb +1 -5
- data/lib/mongoid/persistable/savable.rb +14 -8
- data/lib/mongoid/persistable/settable.rb +1 -5
- data/lib/mongoid/persistable/unsettable.rb +3 -7
- data/lib/mongoid/persistable/updatable.rb +114 -28
- data/lib/mongoid/persistable/upsertable.rb +33 -8
- data/lib/mongoid/persistable.rb +17 -27
- data/lib/mongoid/persistence_context.rb +111 -43
- data/lib/mongoid/positional.rb +1 -5
- data/lib/mongoid/railtie.rb +23 -15
- data/lib/mongoid/railties/bson_object_id_serializer.rb +39 -0
- data/lib/mongoid/railties/console_sandbox.rb +42 -0
- data/lib/mongoid/railties/controller_runtime.rb +21 -6
- data/lib/mongoid/railties/database.rake +19 -2
- data/lib/mongoid/reloadable.rb +45 -42
- data/lib/mongoid/scopable.rb +25 -53
- data/lib/mongoid/search_indexable.rb +167 -0
- data/lib/mongoid/selectable.rb +6 -17
- data/lib/mongoid/serializable.rb +11 -21
- data/lib/mongoid/shardable.rb +50 -16
- data/lib/mongoid/stateful.rb +66 -22
- data/lib/mongoid/stringified_symbol.rb +19 -7
- data/lib/mongoid/tasks/database.rake +25 -0
- data/lib/mongoid/tasks/database.rb +84 -8
- data/lib/mongoid/tasks/encryption.rake +59 -0
- data/lib/mongoid/tasks/encryption.rb +108 -0
- data/lib/mongoid/threaded/lifecycle.rb +6 -26
- data/lib/mongoid/threaded.rb +131 -92
- data/lib/mongoid/timestamps/created/short.rb +1 -1
- data/lib/mongoid/timestamps/created.rb +4 -4
- data/lib/mongoid/timestamps/short.rb +1 -1
- data/lib/mongoid/timestamps/timeless.rb +29 -7
- data/lib/mongoid/timestamps/updated/short.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +3 -5
- data/lib/mongoid/timestamps.rb +1 -1
- data/lib/mongoid/touchable.rb +155 -29
- data/lib/mongoid/traversable.rb +180 -125
- data/lib/mongoid/utils.rb +52 -0
- data/lib/mongoid/validatable/associated.rb +97 -21
- data/lib/mongoid/validatable/format.rb +1 -1
- data/lib/mongoid/validatable/length.rb +1 -1
- data/lib/mongoid/validatable/localizable.rb +2 -4
- data/lib/mongoid/validatable/macros.rb +10 -14
- data/lib/mongoid/validatable/presence.rb +7 -13
- data/lib/mongoid/validatable/queryable.rb +9 -3
- data/lib/mongoid/validatable/uniqueness.rb +26 -39
- data/lib/mongoid/validatable.rb +20 -29
- data/lib/mongoid/version.rb +2 -2
- data/lib/mongoid/warnings.rb +37 -0
- data/lib/mongoid.rb +56 -22
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -5
- data/lib/rails/generators/mongoid/config/templates/mongoid.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +44 -64
- data/lib/rails/generators/mongoid/model/model_generator.rb +4 -1
- data/lib/rails/generators/mongoid_generator.rb +13 -1
- data/lib/rails/mongoid.rb +4 -32
- data/spec/config/mongoid.yml +16 -1
- data/spec/config/mongoid_with_schema_map_uuid.yml +27 -0
- data/spec/integration/active_job_spec.rb +32 -0
- data/spec/integration/app_spec.rb +180 -89
- data/spec/integration/associations/belongs_to_spec.rb +19 -1
- data/spec/integration/associations/embedded_dirty_spec.rb +58 -0
- data/spec/integration/associations/embedded_spec.rb +90 -7
- data/spec/integration/associations/embeds_many_spec.rb +197 -1
- data/spec/integration/associations/embeds_one_spec.rb +19 -1
- data/spec/integration/associations/foreign_key_spec.rb +10 -1
- data/spec/integration/associations/foreign_key_spec_models.rb +1 -1
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +62 -0
- data/spec/integration/associations/has_many_spec.rb +1 -1
- data/spec/integration/associations/has_one_spec.rb +145 -1
- data/spec/integration/associations/nested_attributes_assignment_spec.rb +1 -1
- data/spec/integration/associations/reverse_population_spec.rb +1 -1
- data/spec/integration/associations/reverse_population_spec_models.rb +1 -1
- data/spec/integration/associations/scope_option_spec.rb +102 -0
- data/spec/integration/atomic/modifiers_spec.rb +1 -1
- data/spec/integration/bson_regexp_raw_spec.rb +1 -1
- data/spec/integration/callbacks_models.rb +147 -3
- data/spec/integration/callbacks_spec.rb +398 -8
- data/spec/integration/contextual/empty_spec.rb +142 -0
- data/spec/integration/criteria/alias_query_spec.rb +98 -0
- data/spec/integration/criteria/date_field_spec.rb +2 -2
- data/spec/integration/criteria/default_scope_spec.rb +52 -0
- data/spec/integration/criteria/logical_spec.rb +12 -0
- data/spec/integration/criteria/range_spec.rb +358 -0
- data/spec/integration/criteria/raw_value_spec.rb +525 -0
- data/spec/integration/criteria/time_with_zone_spec.rb +126 -15
- data/spec/integration/discriminator_key_spec.rb +119 -81
- data/spec/integration/discriminator_value_spec.rb +1 -1
- data/spec/integration/document_spec.rb +31 -1
- data/spec/integration/dots_and_dollars_spec.rb +278 -0
- data/spec/integration/encryption_spec.rb +100 -0
- data/spec/integration/i18n_fallbacks_spec.rb +10 -52
- data/spec/integration/matcher_examples_spec.rb +21 -14
- data/spec/integration/matcher_operator_data/bits_all_clear.yml +144 -0
- data/spec/integration/matcher_operator_data/bits_all_set.yml +144 -0
- data/spec/integration/matcher_operator_data/bits_any_clear.yml +144 -0
- data/spec/integration/matcher_operator_data/bits_any_set.yml +144 -0
- data/spec/integration/matcher_operator_data/comment.yml +22 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
- data/spec/integration/matcher_operator_data/in.yml +16 -0
- data/spec/integration/matcher_operator_data/mod.yml +55 -0
- data/spec/integration/matcher_operator_data/size.yml +0 -3
- data/spec/integration/matcher_operator_data/type.yml +64 -0
- data/spec/integration/matcher_operator_data/type_array.yml +15 -0
- data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
- data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
- data/spec/integration/matcher_operator_data/type_code.yml +26 -0
- data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
- data/spec/integration/matcher_operator_data/type_date.yml +39 -0
- data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
- data/spec/integration/matcher_operator_data/type_decimal.yml +37 -0
- data/spec/integration/matcher_operator_data/type_double.yml +15 -0
- data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
- data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
- data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_null.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
- data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
- data/spec/integration/matcher_operator_data/type_string.yml +15 -0
- data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
- data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
- data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
- data/spec/integration/matcher_operator_spec.rb +26 -3
- data/spec/integration/matcher_spec.rb +50 -1
- data/spec/integration/persistence/range_field_spec.rb +351 -0
- data/spec/integration/server_query_spec.rb +1 -1
- data/spec/integration/shardable_spec.rb +1 -1
- data/spec/integration/stringified_symbol_field_spec.rb +17 -3
- data/spec/lite_spec_helper.rb +47 -14
- data/spec/mongoid/association/accessors_spec.rb +31 -19
- data/spec/mongoid/association/auto_save_spec.rb +73 -34
- data/spec/mongoid/association/builders_spec.rb +2 -2
- data/spec/mongoid/association/constrainable_spec.rb +1 -1
- data/spec/mongoid/association/counter_cache_spec.rb +34 -34
- data/spec/mongoid/association/depending_spec.rb +397 -358
- data/spec/mongoid/association/eager_spec.rb +56 -6
- data/spec/mongoid/association/embedded/cyclic_spec.rb +3 -3
- data/spec/mongoid/association/embedded/dirty_spec.rb +3 -3
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +3 -2
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +55 -1
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +110 -23
- data/spec/mongoid/association/embedded/embedded_in_spec.rb +19 -8
- data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +1 -1
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +113 -1
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +712 -203
- data/spec/mongoid/association/embedded/embeds_many_models.rb +189 -1
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +14 -2
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +69 -1
- data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +1 -1
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +26 -1
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +37 -24
- data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +1 -1
- data/spec/mongoid/association/embedded/embeds_one_models.rb +25 -2
- data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +2 -2
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +29 -1
- data/spec/mongoid/association/macros_spec.rb +10 -10
- data/spec/mongoid/association/nested/many_spec.rb +1 -1
- data/spec/mongoid/association/nested/one_spec.rb +17 -13
- data/spec/mongoid/association/options_spec.rb +1 -1
- data/spec/mongoid/association/polymorphic_spec.rb +1 -1
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +3 -2
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +110 -17
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +51 -15
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +113 -59
- data/spec/mongoid/association/referenced/belongs_to_models.rb +12 -0
- data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +22 -2
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +27 -22
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +28 -3
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +32 -3
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +386 -376
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +44 -1
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +57 -3
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +131 -1
- data/spec/mongoid/association/referenced/has_many/eager_spec.rb +24 -7
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +313 -134
- data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +1313 -2109
- data/spec/mongoid/association/referenced/has_many_models.rb +39 -2
- data/spec/mongoid/association/referenced/has_many_query_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_many_spec.rb +47 -1
- data/spec/mongoid/association/referenced/has_one/binding_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +54 -10
- data/spec/mongoid/association/referenced/has_one/eager_spec.rb +18 -2
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +134 -28
- data/spec/mongoid/association/referenced/has_one_models.rb +43 -1
- data/spec/mongoid/association/referenced/has_one_query_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_one_spec.rb +22 -1
- data/spec/mongoid/association/reflections_spec.rb +1 -1
- data/spec/mongoid/association/syncable_spec.rb +47 -33
- data/spec/mongoid/association_spec.rb +1 -1
- data/spec/mongoid/atomic/modifiers_spec.rb +1 -1
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +1 -1
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +1 -1
- data/spec/mongoid/atomic/paths/root_spec.rb +1 -1
- data/spec/mongoid/atomic/paths_spec.rb +65 -27
- data/spec/mongoid/atomic_spec.rb +29 -7
- data/spec/mongoid/atomic_update_preparer_spec.rb +83 -0
- data/spec/mongoid/attributes/dynamic_spec.rb +1 -1
- data/spec/mongoid/attributes/embedded_spec.rb +118 -0
- data/spec/mongoid/attributes/nested_spec.rb +147 -78
- data/spec/mongoid/attributes/nested_spec_models.rb +49 -0
- data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
- data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
- data/spec/mongoid/attributes/projector_spec.rb +41 -0
- data/spec/mongoid/attributes/readonly_spec.rb +23 -23
- data/spec/mongoid/attributes_spec.rb +921 -69
- data/spec/mongoid/cacheable_spec.rb +5 -5
- data/spec/mongoid/changeable_spec.rb +468 -76
- data/spec/mongoid/clients/factory_spec.rb +152 -30
- data/spec/mongoid/clients/options_spec.rb +24 -12
- data/spec/mongoid/clients/sessions_spec.rb +49 -71
- data/spec/mongoid/clients/transactions_spec.rb +971 -176
- data/spec/mongoid/clients/transactions_spec_models.rb +159 -0
- data/spec/mongoid/clients_spec.rb +230 -22
- data/spec/mongoid/collection_configurable_spec.rb +159 -0
- data/spec/mongoid/composable_spec.rb +1 -1
- data/spec/mongoid/config/defaults_spec.rb +99 -0
- data/spec/mongoid/config/encryption_spec.rb +152 -0
- data/spec/mongoid/config/environment_spec.rb +126 -39
- data/spec/mongoid/config/introspection_spec.rb +114 -0
- data/spec/mongoid/config/options_spec.rb +1 -1
- data/spec/mongoid/config_spec.rb +375 -43
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +432 -154
- data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +63 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +95 -20
- data/spec/mongoid/contextual/aggregable/none_spec.rb +49 -0
- data/spec/mongoid/contextual/atomic_spec.rb +329 -87
- data/spec/mongoid/contextual/map_reduce_spec.rb +5 -19
- data/spec/mongoid/contextual/memory_spec.rb +1479 -127
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +194 -0
- data/spec/mongoid/contextual/mongo_spec.rb +3374 -1254
- data/spec/mongoid/contextual/none_spec.rb +79 -68
- data/spec/mongoid/copyable_spec.rb +465 -23
- data/spec/mongoid/copyable_spec_models.rb +1 -1
- data/spec/mongoid/criteria/findable_spec.rb +295 -229
- data/spec/mongoid/criteria/includable_spec.rb +1493 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +55 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +1 -1
- data/spec/mongoid/criteria/marshalable_spec.rb +19 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +38 -38
- data/spec/mongoid/criteria/options_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +1 -74
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +8 -20
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +135 -27
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +32 -12
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +12 -1
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +1 -16
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +74 -8
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +238 -179
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -12
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +1 -12
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +48 -132
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +5 -60
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +12 -1
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +12 -1
- data/spec/mongoid/criteria/queryable/key_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +106 -8
- data/spec/mongoid/criteria/queryable/optional_spec.rb +17 -486
- data/spec/mongoid/criteria/queryable/options_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +700 -26
- data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +149 -683
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +186 -6
- data/spec/mongoid/criteria/queryable/smash_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/storable_spec.rb +87 -1
- data/spec/mongoid/criteria/scopable_spec.rb +128 -1
- data/spec/mongoid/criteria/translator_spec.rb +133 -0
- data/spec/mongoid/criteria_projection_spec.rb +407 -0
- data/spec/mongoid/criteria_spec.rb +1029 -1806
- data/spec/mongoid/document_fields_spec.rb +180 -5
- data/spec/mongoid/document_persistence_context_spec.rb +77 -1
- data/spec/mongoid/document_query_spec.rb +55 -4
- data/spec/mongoid/document_spec.rb +43 -172
- data/spec/mongoid/equality_spec.rb +7 -8
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +1 -1
- data/spec/mongoid/errors/attribute_not_loaded_spec.rb +32 -0
- data/spec/mongoid/errors/callback_spec.rb +1 -1
- data/spec/mongoid/errors/delete_restriction_spec.rb +2 -2
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +1 -1
- data/spec/mongoid/errors/document_not_found_spec.rb +77 -1
- data/spec/mongoid/errors/invalid_collection_spec.rb +1 -1
- data/spec/mongoid/errors/{eager_load_spec.rb → invalid_config_file_spec.rb} +6 -6
- data/spec/mongoid/errors/invalid_config_option_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_option_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_spec.rb +2 -2
- data/spec/mongoid/errors/invalid_field_type_spec.rb +56 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_includes_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_index_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_options_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_path_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_relation_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_scope_spec.rb +2 -2
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_time_spec.rb +1 -1
- data/spec/mongoid/errors/inverse_not_found_spec.rb +1 -1
- data/spec/mongoid/errors/mixed_client_configuration_spec.rb +1 -1
- data/spec/mongoid/errors/mixed_relations_spec.rb +1 -1
- data/spec/mongoid/errors/mongoid_error_spec.rb +4 -4
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +1 -1
- data/spec/mongoid/errors/no_client_config_spec.rb +1 -1
- data/spec/mongoid/errors/no_client_database_spec.rb +1 -1
- data/spec/mongoid/errors/no_client_hosts_spec.rb +1 -1
- data/spec/mongoid/errors/no_clients_config_spec.rb +1 -1
- data/spec/mongoid/errors/no_environment_spec.rb +4 -4
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +1 -1
- data/spec/mongoid/errors/no_metadata_spec.rb +1 -1
- data/spec/mongoid/errors/no_parent_spec.rb +1 -1
- data/spec/mongoid/errors/readonly_attribute_spec.rb +1 -1
- data/spec/mongoid/errors/readonly_document_spec.rb +3 -3
- data/spec/mongoid/errors/scope_overwrite_spec.rb +1 -1
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +2 -2
- data/spec/mongoid/errors/unknown_attribute_spec.rb +3 -3
- data/spec/mongoid/errors/unsaved_document_spec.rb +1 -1
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +1 -1
- data/spec/mongoid/errors/validations_spec.rb +1 -1
- data/spec/mongoid/extensions/array_spec.rb +19 -265
- data/spec/mongoid/extensions/big_decimal_spec.rb +713 -213
- data/spec/mongoid/extensions/binary_spec.rb +45 -10
- data/spec/mongoid/extensions/boolean_spec.rb +69 -83
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +15 -11
- data/spec/mongoid/extensions/date_spec.rb +74 -22
- data/spec/mongoid/extensions/date_time_spec.rb +18 -19
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
- data/spec/mongoid/extensions/false_class_spec.rb +2 -9
- data/spec/mongoid/extensions/float_spec.rb +56 -84
- data/spec/mongoid/extensions/hash_spec.rb +45 -219
- data/spec/mongoid/extensions/integer_spec.rb +53 -73
- data/spec/mongoid/extensions/module_spec.rb +1 -1
- data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
- data/spec/mongoid/extensions/object_id_spec.rb +1 -1
- data/spec/mongoid/extensions/object_spec.rb +1 -177
- data/spec/mongoid/extensions/range_spec.rb +254 -64
- data/spec/mongoid/extensions/raw_value_spec.rb +67 -0
- data/spec/mongoid/extensions/regexp_spec.rb +59 -34
- data/spec/mongoid/extensions/set_spec.rb +105 -1
- data/spec/mongoid/extensions/string_spec.rb +21 -104
- data/spec/mongoid/extensions/stringified_symbol_spec.rb +1 -1
- data/spec/mongoid/extensions/symbol_spec.rb +15 -53
- data/spec/mongoid/extensions/time_spec.rb +345 -131
- data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -107
- data/spec/mongoid/extensions/true_class_spec.rb +2 -9
- data/spec/mongoid/factory_spec.rb +63 -2
- data/spec/mongoid/fields/foreign_key_spec.rb +282 -120
- data/spec/mongoid/fields/localized_spec.rb +85 -42
- data/spec/mongoid/fields/standard_spec.rb +1 -1
- data/spec/mongoid/fields_spec.rb +826 -121
- data/spec/mongoid/findable_spec.rb +442 -80
- data/spec/mongoid/indexable/specification_spec.rb +132 -14
- data/spec/mongoid/indexable_spec.rb +361 -23
- data/spec/mongoid/inspectable_spec.rb +93 -5
- data/spec/mongoid/interceptable_spec.rb +926 -116
- data/spec/mongoid/interceptable_spec_models.rb +236 -4
- data/spec/mongoid/loading_spec.rb +110 -0
- data/spec/mongoid/loggable_spec.rb +1 -1
- data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
- data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
- data/spec/mongoid/matcher/extract_attribute_spec.rb +5 -15
- data/spec/mongoid/mongoizable_spec.rb +286 -0
- data/spec/mongoid/monkey_patches_spec.rb +211 -0
- data/spec/mongoid/persistable/creatable_spec.rb +5 -5
- data/spec/mongoid/persistable/deletable_spec.rb +267 -27
- data/spec/mongoid/persistable/destroyable_spec.rb +409 -24
- data/spec/mongoid/persistable/incrementable_spec.rb +46 -9
- data/spec/mongoid/persistable/logical_spec.rb +42 -5
- data/spec/mongoid/persistable/maxable_spec.rb +147 -0
- data/spec/mongoid/persistable/minable_spec.rb +147 -0
- data/spec/mongoid/persistable/multipliable_spec.rb +227 -0
- data/spec/mongoid/persistable/poppable_spec.rb +41 -5
- data/spec/mongoid/persistable/pullable_spec.rb +81 -9
- data/spec/mongoid/persistable/pushable_spec.rb +81 -9
- data/spec/mongoid/persistable/renamable_spec.rb +40 -4
- data/spec/mongoid/persistable/savable_spec.rb +114 -20
- data/spec/mongoid/persistable/settable_spec.rb +77 -10
- data/spec/mongoid/persistable/unsettable_spec.rb +41 -5
- data/spec/mongoid/persistable/updatable_spec.rb +64 -52
- data/spec/mongoid/persistable/upsertable_spec.rb +124 -4
- data/spec/mongoid/persistable_spec.rb +4 -4
- data/spec/mongoid/persistence_context_spec.rb +58 -59
- data/spec/mongoid/positional_spec.rb +1 -1
- data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +24 -0
- data/spec/mongoid/railties/console_sandbox_spec.rb +44 -0
- data/spec/mongoid/relations/proxy_spec.rb +7 -7
- data/spec/mongoid/reloadable_spec.rb +255 -30
- data/spec/mongoid/scopable_spec.rb +198 -58
- data/spec/mongoid/search_indexable_spec.rb +147 -0
- data/spec/mongoid/selectable_spec.rb +7 -7
- data/spec/mongoid/serializable_spec.rb +19 -40
- data/spec/mongoid/shardable_models.rb +15 -0
- data/spec/mongoid/shardable_spec.rb +181 -31
- data/spec/mongoid/stateful_spec.rb +152 -10
- data/spec/mongoid/tasks/database_rake_spec.rb +193 -42
- data/spec/mongoid/tasks/database_spec.rb +175 -2
- data/spec/mongoid/tasks/encryption_spec.rb +187 -0
- data/spec/mongoid/threaded_spec.rb +40 -3
- data/spec/mongoid/timestamps/created/short_spec.rb +2 -2
- data/spec/mongoid/timestamps/created_spec.rb +2 -2
- data/spec/mongoid/timestamps/timeless_spec.rb +3 -3
- data/spec/mongoid/timestamps/updated/short_spec.rb +4 -4
- data/spec/mongoid/timestamps/updated_spec.rb +4 -4
- data/spec/mongoid/timestamps_spec.rb +399 -11
- data/spec/mongoid/timestamps_spec_models.rb +68 -0
- data/spec/mongoid/touchable_spec.rb +971 -54
- data/spec/mongoid/touchable_spec_models.rb +154 -0
- data/spec/mongoid/traversable_spec.rb +79 -37
- data/spec/mongoid/validatable/associated_spec.rb +14 -31
- data/spec/mongoid/validatable/format_spec.rb +1 -1
- data/spec/mongoid/validatable/length_spec.rb +1 -1
- data/spec/mongoid/validatable/numericality_spec.rb +1 -1
- data/spec/mongoid/validatable/presence_spec.rb +27 -23
- data/spec/mongoid/validatable/uniqueness_spec.rb +170 -99
- data/spec/mongoid/validatable_spec.rb +4 -4
- data/spec/mongoid/warnings_spec.rb +36 -0
- data/spec/mongoid_spec.rb +61 -11
- data/spec/rails/controller_extension/controller_runtime_spec.rb +3 -3
- data/spec/rails/mongoid_spec.rb +28 -132
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/cluster_config.rb +24 -4
- data/spec/shared/lib/mrss/constraints.rb +77 -29
- data/spec/shared/lib/mrss/docker_runner.rb +40 -4
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +64 -1
- data/spec/shared/lib/mrss/server_version_registry.rb +78 -34
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/share/Dockerfile.erb +123 -71
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +2 -1
- data/spec/shared/shlib/server.sh +187 -40
- data/spec/shared/shlib/set_env.sh +49 -31
- data/spec/spec_helper.rb +46 -49
- data/spec/support/authorization.rb +1 -1
- data/spec/support/client_registry.rb +10 -0
- data/spec/support/constraints.rb +25 -1
- data/spec/support/crypt/models.rb +50 -0
- data/spec/support/crypt.rb +80 -0
- data/spec/support/expectations.rb +1 -1
- data/spec/support/feature_sandbox.rb +72 -0
- data/spec/support/helpers.rb +1 -0
- data/spec/support/immutable_ids.rb +119 -0
- data/spec/support/macros.rb +107 -1
- data/spec/support/models/account.rb +2 -2
- data/spec/support/models/acolyte.rb +1 -1
- data/spec/support/models/actor.rb +1 -1
- data/spec/support/models/actress.rb +1 -1
- data/spec/support/models/address.rb +7 -1
- data/spec/support/models/address_component.rb +1 -1
- data/spec/support/models/address_number.rb +1 -1
- data/spec/support/models/agency.rb +1 -1
- data/spec/support/models/agent.rb +1 -1
- data/spec/support/models/album.rb +1 -1
- data/spec/support/models/alert.rb +1 -1
- data/spec/support/models/animal.rb +1 -1
- data/spec/support/models/answer.rb +1 -1
- data/spec/support/models/appointment.rb +1 -1
- data/spec/support/models/armrest.rb +1 -1
- data/spec/support/models/array_field.rb +1 -1
- data/spec/support/models/article.rb +1 -1
- data/spec/support/models/artist.rb +3 -2
- data/spec/support/models/artwork.rb +1 -1
- data/spec/support/models/audible_sound.rb +4 -0
- data/spec/support/models/audio.rb +1 -1
- data/spec/support/models/augmentation.rb +13 -1
- data/spec/support/models/author.rb +1 -1
- data/spec/support/models/baby.rb +1 -1
- data/spec/support/models/band.rb +13 -1
- data/spec/support/models/bar.rb +1 -1
- data/spec/support/models/basic.rb +1 -1
- data/spec/support/models/bed.rb +1 -1
- data/spec/support/models/big_palette.rb +1 -1
- data/spec/support/models/birthday.rb +1 -1
- data/spec/support/models/bolt.rb +8 -0
- data/spec/support/models/bomb.rb +1 -1
- data/spec/support/models/book.rb +2 -1
- data/spec/support/models/breed.rb +1 -1
- data/spec/support/models/browser.rb +1 -1
- data/spec/support/models/building.rb +3 -1
- data/spec/support/models/building_address.rb +1 -1
- data/spec/support/models/bus.rb +1 -1
- data/spec/support/models/business.rb +1 -1
- data/spec/support/models/callback_test.rb +1 -1
- data/spec/support/models/canvas.rb +1 -1
- data/spec/support/models/car.rb +1 -1
- data/spec/support/models/cat.rb +1 -1
- data/spec/support/models/catalog.rb +25 -0
- data/spec/support/models/category.rb +1 -1
- data/spec/support/models/child.rb +1 -1
- data/spec/support/models/child_doc.rb +4 -4
- data/spec/support/models/church.rb +1 -1
- data/spec/support/models/circle.rb +1 -1
- data/spec/support/models/circuit.rb +1 -1
- data/spec/support/models/circus.rb +4 -1
- data/spec/support/models/code.rb +3 -1
- data/spec/support/models/coding/pull_request.rb +1 -1
- data/spec/support/models/coding.rb +1 -1
- data/spec/support/models/comment.rb +1 -1
- data/spec/support/models/company.rb +1 -1
- data/spec/support/models/consumption_period.rb +1 -1
- data/spec/support/models/contextable_item.rb +1 -1
- data/spec/support/models/contractor.rb +1 -1
- data/spec/support/models/cookie.rb +1 -1
- data/spec/support/models/country_code.rb +3 -1
- data/spec/support/models/courier_job.rb +1 -1
- data/spec/support/models/cover.rb +11 -0
- data/spec/support/models/crate.rb +1 -1
- data/spec/support/models/customer.rb +1 -1
- data/spec/support/models/customer_address.rb +1 -1
- data/spec/support/models/deed.rb +1 -1
- data/spec/support/models/definition.rb +1 -1
- data/spec/support/models/delegating_patient.rb +1 -1
- data/spec/support/models/description.rb +1 -1
- data/spec/support/models/dictionary.rb +1 -1
- data/spec/support/models/division.rb +1 -1
- data/spec/support/models/doctor.rb +1 -1
- data/spec/support/models/dog.rb +1 -1
- data/spec/support/models/dokument.rb +1 -1
- data/spec/support/models/draft.rb +1 -1
- data/spec/support/models/dragon.rb +1 -1
- data/spec/support/models/driver.rb +1 -1
- data/spec/support/models/drug.rb +1 -1
- data/spec/support/models/dungeon.rb +1 -1
- data/spec/support/models/edit.rb +1 -1
- data/spec/support/models/email.rb +1 -1
- data/spec/support/models/employer.rb +1 -1
- data/spec/support/models/entry.rb +1 -1
- data/spec/support/models/eraser.rb +1 -1
- data/spec/support/models/even.rb +1 -1
- data/spec/support/models/event.rb +1 -1
- data/spec/support/models/exhibition.rb +1 -1
- data/spec/support/models/exhibitor.rb +1 -1
- data/spec/support/models/explosion.rb +1 -1
- data/spec/support/models/eye.rb +1 -1
- data/spec/support/models/eye_bowl.rb +1 -1
- data/spec/support/models/face.rb +1 -1
- data/spec/support/models/fanatic.rb +9 -0
- data/spec/support/models/favorite.rb +8 -2
- data/spec/support/models/filesystem.rb +1 -1
- data/spec/support/models/fire_hydrant.rb +1 -1
- data/spec/support/models/firefox.rb +1 -1
- data/spec/support/models/fish.rb +1 -1
- data/spec/support/models/folder.rb +1 -1
- data/spec/support/models/folder_item.rb +1 -1
- data/spec/support/models/fruits.rb +1 -1
- data/spec/support/models/game.rb +1 -1
- data/spec/support/models/ghost.rb +1 -1
- data/spec/support/models/guitar.rb +1 -1
- data/spec/support/models/hole.rb +13 -0
- data/spec/support/models/home.rb +1 -1
- data/spec/support/models/house.rb +1 -1
- data/spec/support/models/html_writer.rb +1 -1
- data/spec/support/models/id_key.rb +1 -1
- data/spec/support/models/idnodef.rb +1 -1
- data/spec/support/models/image.rb +1 -1
- data/spec/support/models/implant.rb +10 -1
- data/spec/support/models/instrument.rb +1 -1
- data/spec/support/models/item.rb +1 -1
- data/spec/support/models/jar.rb +1 -1
- data/spec/support/models/kaleidoscope.rb +1 -1
- data/spec/support/models/kangaroo.rb +1 -1
- data/spec/support/models/label.rb +5 -2
- data/spec/support/models/language.rb +1 -1
- data/spec/support/models/lat_lng.rb +1 -1
- data/spec/support/models/league.rb +1 -1
- data/spec/support/models/learner.rb +1 -1
- data/spec/support/models/line_item.rb +1 -1
- data/spec/support/models/location.rb +1 -1
- data/spec/support/models/login.rb +1 -1
- data/spec/support/models/manufacturer.rb +1 -1
- data/spec/support/models/meat.rb +1 -1
- data/spec/support/models/membership.rb +2 -1
- data/spec/support/models/message.rb +1 -1
- data/spec/support/models/minim.rb +1 -1
- data/spec/support/models/mixed_drink.rb +1 -1
- data/spec/support/models/mop.rb +10 -1
- data/spec/support/models/movie.rb +1 -1
- data/spec/support/models/my_hash.rb +1 -1
- data/spec/support/models/name.rb +11 -1
- data/spec/support/models/name_only.rb +1 -1
- data/spec/support/models/node.rb +1 -1
- data/spec/support/models/note.rb +1 -1
- data/spec/support/models/nut.rb +8 -0
- data/spec/support/models/odd.rb +1 -1
- data/spec/support/models/order.rb +3 -1
- data/spec/support/models/ordered_post.rb +2 -2
- data/spec/support/models/ordered_preference.rb +1 -1
- data/spec/support/models/oscar.rb +1 -1
- data/spec/support/models/other_owner_object.rb +1 -1
- data/spec/support/models/override.rb +1 -1
- data/spec/support/models/ownable.rb +1 -1
- data/spec/support/models/owner.rb +1 -1
- data/spec/support/models/pack.rb +1 -1
- data/spec/support/models/page.rb +1 -1
- data/spec/support/models/page_question.rb +1 -1
- data/spec/support/models/palette.rb +1 -1
- data/spec/support/models/parent.rb +1 -1
- data/spec/support/models/parent_doc.rb +1 -1
- data/spec/support/models/passport.rb +15 -1
- data/spec/support/models/patient.rb +1 -1
- data/spec/support/models/pdf_writer.rb +1 -1
- data/spec/support/models/pencil.rb +1 -1
- data/spec/support/models/person.rb +19 -1
- data/spec/support/models/pet.rb +1 -1
- data/spec/support/models/pet_owner.rb +1 -1
- data/spec/support/models/phone.rb +3 -2
- data/spec/support/models/piano.rb +1 -1
- data/spec/support/models/pizza.rb +1 -1
- data/spec/support/models/player.rb +3 -1
- data/spec/support/models/post.rb +1 -1
- data/spec/support/models/post_genre.rb +1 -1
- data/spec/support/models/powerup.rb +13 -1
- data/spec/support/models/preference.rb +1 -1
- data/spec/support/models/princess.rb +1 -1
- data/spec/support/models/product.rb +2 -1
- data/spec/support/models/profile.rb +1 -1
- data/spec/support/models/pronunciation.rb +1 -1
- data/spec/support/models/pub.rb +1 -1
- data/spec/support/models/publication/encyclopedia.rb +1 -1
- data/spec/support/models/publication/review.rb +1 -1
- data/spec/support/models/publication.rb +1 -1
- data/spec/support/models/purchase.rb +1 -1
- data/spec/support/models/purchased_item.rb +11 -0
- data/spec/support/models/purse.rb +9 -0
- data/spec/support/models/question.rb +1 -1
- data/spec/support/models/quiz.rb +1 -1
- data/spec/support/models/rating.rb +1 -1
- data/spec/support/models/record.rb +1 -1
- data/spec/support/models/registry.rb +2 -1
- data/spec/support/models/role.rb +1 -1
- data/spec/support/models/root_category.rb +1 -1
- data/spec/support/models/sandbox/app/models/app_models_message.rb +4 -0
- data/spec/support/models/sandbox/lib/models/lib_models_message.rb +4 -0
- data/spec/support/models/sandbox/sandbox_message.rb +4 -0
- data/spec/support/models/sandbox/sandbox_user.rb +4 -0
- data/spec/support/models/sandbox/subdir/sandbox_comment.rb +4 -0
- data/spec/support/models/sandwich.rb +1 -1
- data/spec/support/models/scheduler.rb +1 -1
- data/spec/support/models/school.rb +15 -0
- data/spec/support/models/scribe.rb +1 -1
- data/spec/support/models/sealer.rb +8 -0
- data/spec/support/models/seat.rb +1 -1
- data/spec/support/models/seo.rb +1 -1
- data/spec/support/models/series.rb +1 -1
- data/spec/support/models/server.rb +1 -1
- data/spec/support/models/service.rb +1 -1
- data/spec/support/models/shape.rb +1 -1
- data/spec/support/models/shelf.rb +1 -1
- data/spec/support/models/shield.rb +19 -0
- data/spec/support/models/shipment_address.rb +1 -1
- data/spec/support/models/shipping_container.rb +1 -1
- data/spec/support/models/shipping_pack.rb +1 -1
- data/spec/support/models/shirt.rb +12 -0
- data/spec/support/models/shop.rb +1 -1
- data/spec/support/models/short_agent.rb +1 -1
- data/spec/support/models/short_quiz.rb +1 -1
- data/spec/support/models/simple.rb +1 -1
- data/spec/support/models/slave.rb +1 -1
- data/spec/support/models/song.rb +1 -1
- data/spec/support/models/sound.rb +1 -1
- data/spec/support/models/spacer.rb +8 -0
- data/spec/support/models/square.rb +1 -1
- data/spec/support/models/staff.rb +1 -1
- data/spec/support/models/store_as_dup_test1.rb +1 -1
- data/spec/support/models/store_as_dup_test2.rb +1 -1
- data/spec/support/models/store_as_dup_test3.rb +1 -1
- data/spec/support/models/store_as_dup_test4.rb +1 -1
- data/spec/support/models/strategy.rb +1 -1
- data/spec/support/models/student.rb +15 -0
- data/spec/support/models/sub_item.rb +1 -1
- data/spec/support/models/subscription.rb +1 -1
- data/spec/support/models/survey.rb +1 -1
- data/spec/support/models/symptom.rb +1 -1
- data/spec/support/models/system_role.rb +1 -0
- data/spec/support/models/tag.rb +1 -1
- data/spec/support/models/target.rb +1 -1
- data/spec/support/models/template.rb +1 -1
- data/spec/support/models/thing.rb +1 -1
- data/spec/support/models/threadlocker.rb +8 -0
- data/spec/support/models/title.rb +1 -1
- data/spec/support/models/tool.rb +1 -1
- data/spec/support/models/topping.rb +1 -1
- data/spec/support/models/toy.rb +1 -1
- data/spec/support/models/track.rb +1 -1
- data/spec/support/models/translation.rb +1 -1
- data/spec/support/models/tree.rb +1 -1
- data/spec/support/models/truck.rb +1 -1
- data/spec/support/models/updatable.rb +1 -1
- data/spec/support/models/user.rb +1 -1
- data/spec/support/models/user_account.rb +1 -1
- data/spec/support/models/validation_callback.rb +1 -1
- data/spec/support/models/vehicle.rb +1 -1
- data/spec/support/models/version.rb +1 -1
- data/spec/support/models/vertex.rb +1 -1
- data/spec/support/models/vet_visit.rb +1 -1
- data/spec/support/models/video.rb +1 -1
- data/spec/support/models/video_game.rb +1 -1
- data/spec/support/models/washer.rb +8 -0
- data/spec/support/models/weapon.rb +13 -1
- data/spec/support/models/wiki_page.rb +1 -1
- data/spec/support/models/word.rb +1 -1
- data/spec/support/models/word_origin.rb +1 -1
- data/spec/support/models/writer.rb +1 -1
- data/spec/support/rails_mock.rb +32 -0
- data/spec/support/schema_maps/schema_map_aws.json +17 -0
- data/spec/support/schema_maps/schema_map_aws_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_azure.json +17 -0
- data/spec/support/schema_maps/schema_map_azure_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_gcp.json +17 -0
- data/spec/support/schema_maps/schema_map_gcp_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_kmip.json +17 -0
- data/spec/support/schema_maps/schema_map_kmip_key_alt_names.json +12 -0
- data/spec/support/schema_maps/schema_map_local.json +18 -0
- data/spec/support/schema_maps/schema_map_local_key_alt_names.json +12 -0
- data/spec/support/shared/time.rb +3 -22
- data/spec/support/sinatra_mock.rb +7 -0
- data/spec/support/spec_config.rb +42 -7
- data.tar.gz.sig +0 -0
- metadata +883 -562
- metadata.gz.sig +0 -0
- data/lib/mongoid/association/referenced/eager.rb +0 -184
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +0 -128
- data/lib/mongoid/contextual/geo_near.rb +0 -269
- data/lib/mongoid/errors/eager_load.rb +0 -26
- data/lib/mongoid/errors/invalid_session_use.rb +0 -26
- data/lib/mongoid/errors/invalid_storage_parent.rb +0 -28
- data/lib/mongoid/errors/invalid_value.rb +0 -18
- data/lib/mongoid/query_cache.rb +0 -333
- data/lib/support/ruby_version.rb +0 -29
- data/spec/mongoid/contextual/geo_near_spec.rb +0 -472
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -61
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -61
- data/spec/mongoid/extensions_spec.rb +0 -32
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -61
- data/spec/mongoid/query_cache_spec.rb +0 -978
- data/spec/support/cluster_config.rb +0 -158
- data/spec/support/session_registry.rb +0 -50
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
|
-
#
|
|
2
|
+
# rubocop:todo all
|
|
3
3
|
|
|
4
|
+
require 'mongoid/atomic_update_preparer'
|
|
5
|
+
require "mongoid/contextual/mongo/documents_loader"
|
|
4
6
|
require "mongoid/contextual/atomic"
|
|
5
7
|
require "mongoid/contextual/aggregable/mongo"
|
|
6
8
|
require "mongoid/contextual/command"
|
|
7
|
-
require "mongoid/contextual/geo_near"
|
|
8
9
|
require "mongoid/contextual/map_reduce"
|
|
9
10
|
require "mongoid/association/eager_loadable"
|
|
10
11
|
|
|
11
12
|
module Mongoid
|
|
12
13
|
module Contextual
|
|
14
|
+
|
|
15
|
+
# Context object used for performing bulk query and persistence
|
|
16
|
+
# operations on documents which are persisted in the database and
|
|
17
|
+
# have not been loaded into application memory.
|
|
13
18
|
class Mongo
|
|
14
19
|
extend Forwardable
|
|
15
20
|
include Enumerable
|
|
@@ -19,8 +24,6 @@ module Mongoid
|
|
|
19
24
|
include Queryable
|
|
20
25
|
|
|
21
26
|
# Options constant.
|
|
22
|
-
#
|
|
23
|
-
# @since 5.0.0
|
|
24
27
|
OPTIONS = [ :hint,
|
|
25
28
|
:limit,
|
|
26
29
|
:skip,
|
|
@@ -38,17 +41,17 @@ module Mongoid
|
|
|
38
41
|
# @attribute [r] view The Mongo collection view.
|
|
39
42
|
attr_reader :view
|
|
40
43
|
|
|
41
|
-
#
|
|
44
|
+
# Run an explain on the criteria.
|
|
42
45
|
#
|
|
43
|
-
# @example
|
|
44
|
-
#
|
|
46
|
+
# @example Explain the criteria.
|
|
47
|
+
# Band.where(name: "Depeche Mode").explain
|
|
45
48
|
#
|
|
46
|
-
# @
|
|
49
|
+
# @param [ Hash ] options customizable options (See Mongo::Collection::View::Explainable)
|
|
47
50
|
#
|
|
48
|
-
# @
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
# @return [ Hash ] The explain result.
|
|
52
|
+
def_delegator :view, :explain
|
|
53
|
+
|
|
54
|
+
attr_reader :documents_loader
|
|
52
55
|
|
|
53
56
|
# Get the number of documents matching the query.
|
|
54
57
|
#
|
|
@@ -67,11 +70,16 @@ module Mongoid
|
|
|
67
70
|
# into the count.
|
|
68
71
|
#
|
|
69
72
|
# @return [ Integer ] The number of matches.
|
|
70
|
-
#
|
|
71
|
-
# @since 3.0.0
|
|
72
73
|
def count(options = {}, &block)
|
|
73
74
|
return super(&block) if block_given?
|
|
74
|
-
|
|
75
|
+
|
|
76
|
+
if valid_for_count_documents?
|
|
77
|
+
view.count_documents(options)
|
|
78
|
+
else
|
|
79
|
+
# TODO: Remove this when we remove the deprecated for_js API.
|
|
80
|
+
# https://jira.mongodb.org/browse/MONGOID-5681
|
|
81
|
+
view.count(options)
|
|
82
|
+
end
|
|
75
83
|
end
|
|
76
84
|
|
|
77
85
|
# Get the estimated number of documents matching the query.
|
|
@@ -88,9 +96,13 @@ module Mongoid
|
|
|
88
96
|
# @return [ Integer ] The number of matches.
|
|
89
97
|
def estimated_count(options = {})
|
|
90
98
|
unless self.criteria.selector.empty?
|
|
91
|
-
|
|
99
|
+
if klass.default_scoping?
|
|
100
|
+
raise Mongoid::Errors::InvalidEstimatedCountScoping.new(self.klass)
|
|
101
|
+
else
|
|
102
|
+
raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
|
|
103
|
+
end
|
|
92
104
|
end
|
|
93
|
-
|
|
105
|
+
view.estimated_document_count(options)
|
|
94
106
|
end
|
|
95
107
|
|
|
96
108
|
# Delete all documents in the database that match the selector.
|
|
@@ -99,8 +111,6 @@ module Mongoid
|
|
|
99
111
|
# context.delete
|
|
100
112
|
#
|
|
101
113
|
# @return [ nil ] Nil.
|
|
102
|
-
#
|
|
103
|
-
# @since 3.0.0
|
|
104
114
|
def delete
|
|
105
115
|
view.delete_many.deleted_count
|
|
106
116
|
end
|
|
@@ -112,8 +122,6 @@ module Mongoid
|
|
|
112
122
|
# context.destroy
|
|
113
123
|
#
|
|
114
124
|
# @return [ nil ] Nil.
|
|
115
|
-
#
|
|
116
|
-
# @since 3.0.0
|
|
117
125
|
def destroy
|
|
118
126
|
each.inject(0) do |count, doc|
|
|
119
127
|
doc.destroy
|
|
@@ -128,14 +136,15 @@ module Mongoid
|
|
|
128
136
|
# @example Get the distinct values.
|
|
129
137
|
# context.distinct(:name)
|
|
130
138
|
#
|
|
131
|
-
# @param [ String
|
|
139
|
+
# @param [ String | Symbol ] field The name of the field.
|
|
132
140
|
#
|
|
133
141
|
# @return [ Array<Object> ] The distinct values for the field.
|
|
134
|
-
#
|
|
135
|
-
# @since 3.0.0
|
|
136
142
|
def distinct(field)
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
name = klass.cleanse_localized_field_names(field)
|
|
144
|
+
|
|
145
|
+
view.distinct(name).map do |value|
|
|
146
|
+
is_translation = "#{name}_translations" == field.to_s
|
|
147
|
+
recursive_demongoize(name, value, is_translation)
|
|
139
148
|
end
|
|
140
149
|
end
|
|
141
150
|
|
|
@@ -148,14 +157,11 @@ module Mongoid
|
|
|
148
157
|
# end
|
|
149
158
|
#
|
|
150
159
|
# @return [ Enumerator ] The enumerator.
|
|
151
|
-
#
|
|
152
|
-
# @since 3.0.0
|
|
153
160
|
def each(&block)
|
|
154
161
|
if block_given?
|
|
155
162
|
documents_for_iteration.each do |doc|
|
|
156
163
|
yield_document(doc, &block)
|
|
157
164
|
end
|
|
158
|
-
@cache_loaded = true
|
|
159
165
|
self
|
|
160
166
|
else
|
|
161
167
|
to_enum
|
|
@@ -167,34 +173,30 @@ module Mongoid
|
|
|
167
173
|
# @example Do any documents exist for the context.
|
|
168
174
|
# context.exists?
|
|
169
175
|
#
|
|
170
|
-
# @
|
|
171
|
-
#
|
|
172
|
-
# used to determine the value.
|
|
176
|
+
# @example Do any documents exist for given _id.
|
|
177
|
+
# context.exists?(BSON::ObjectId(...))
|
|
173
178
|
#
|
|
174
|
-
# @
|
|
179
|
+
# @example Do any documents exist for given conditions.
|
|
180
|
+
# context.exists?(name: "...")
|
|
175
181
|
#
|
|
176
|
-
# @since
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
182
|
+
# @note We don't use count here since Mongo does not use counted
|
|
183
|
+
# b-tree indexes.
|
|
184
|
+
#
|
|
185
|
+
# @param [ Hash | Object | false ] id_or_conditions an _id to
|
|
186
|
+
# search for, a hash of conditions, nil or false.
|
|
187
|
+
#
|
|
188
|
+
# @return [ true | false ] If the count is more than zero.
|
|
189
|
+
# Always false if passed nil or false.
|
|
190
|
+
def exists?(id_or_conditions = :none)
|
|
191
|
+
return false if self.view.limit == 0
|
|
192
|
+
case id_or_conditions
|
|
193
|
+
when :none then !!(view.projection(_id: 1).limit(1).first)
|
|
194
|
+
when nil, false then false
|
|
195
|
+
when Hash then Mongo.new(criteria.where(id_or_conditions)).exists?
|
|
196
|
+
else Mongo.new(criteria.where(_id: id_or_conditions)).exists?
|
|
183
197
|
end
|
|
184
198
|
end
|
|
185
199
|
|
|
186
|
-
# Run an explain on the criteria.
|
|
187
|
-
#
|
|
188
|
-
# @example Explain the criteria.
|
|
189
|
-
# Band.where(name: "Depeche Mode").explain
|
|
190
|
-
#
|
|
191
|
-
# @return [ Hash ] The explain result.
|
|
192
|
-
#
|
|
193
|
-
# @since 3.0.0
|
|
194
|
-
def explain
|
|
195
|
-
view.explain
|
|
196
|
-
end
|
|
197
|
-
|
|
198
200
|
# Execute the find and modify command, used for MongoDB's
|
|
199
201
|
# $findAndModify.
|
|
200
202
|
#
|
|
@@ -204,13 +206,11 @@ module Mongoid
|
|
|
204
206
|
# @param [ Hash ] update The updates.
|
|
205
207
|
# @param [ Hash ] options The command options.
|
|
206
208
|
#
|
|
207
|
-
# @option options [ :before
|
|
209
|
+
# @option options [ :before | :after ] :return_document Return the updated document
|
|
208
210
|
# from before or after update.
|
|
209
|
-
# @option options [ true
|
|
211
|
+
# @option options [ true | false ] :upsert Create the document if it doesn't exist.
|
|
210
212
|
#
|
|
211
213
|
# @return [ Document ] The result of the command.
|
|
212
|
-
#
|
|
213
|
-
# @since 5.0.0
|
|
214
214
|
def find_one_and_update(update, options = {})
|
|
215
215
|
if doc = view.find_one_and_update(update, options)
|
|
216
216
|
Factory.from_db(klass, doc)
|
|
@@ -226,13 +226,11 @@ module Mongoid
|
|
|
226
226
|
# @param [ Hash ] replacement The replacement.
|
|
227
227
|
# @param [ Hash ] options The command options.
|
|
228
228
|
#
|
|
229
|
-
# @option options [ :before
|
|
229
|
+
# @option options [ :before | :after ] :return_document Return the updated document
|
|
230
230
|
# from before or after update.
|
|
231
|
-
# @option options [ true
|
|
231
|
+
# @option options [ true | false ] :upsert Create the document if it doesn't exist.
|
|
232
232
|
#
|
|
233
233
|
# @return [ Document ] The result of the command.
|
|
234
|
-
#
|
|
235
|
-
# @since 5.0.0
|
|
236
234
|
def find_one_and_replace(replacement, options = {})
|
|
237
235
|
if doc = view.find_one_and_replace(replacement, options)
|
|
238
236
|
Factory.from_db(klass, doc)
|
|
@@ -246,112 +244,22 @@ module Mongoid
|
|
|
246
244
|
# context.find_one_and_delete
|
|
247
245
|
#
|
|
248
246
|
# @return [ Document ] The result of the command.
|
|
249
|
-
#
|
|
250
|
-
# @since 5.0.0
|
|
251
247
|
def find_one_and_delete
|
|
252
248
|
if doc = view.find_one_and_delete
|
|
253
249
|
Factory.from_db(klass, doc)
|
|
254
250
|
end
|
|
255
251
|
end
|
|
256
252
|
|
|
257
|
-
# Get the first document in the database for the criteria's selector.
|
|
258
|
-
#
|
|
259
|
-
# @example Get the first document.
|
|
260
|
-
# context.first
|
|
261
|
-
#
|
|
262
|
-
# @note Automatically adding a sort on _id when no other sort is
|
|
263
|
-
# defined on the criteria has the potential to cause bad performance issues.
|
|
264
|
-
# If you experience unexpected poor performance when using #first or #last
|
|
265
|
-
# and have no sort defined on the criteria, use the option { id_sort: :none }.
|
|
266
|
-
# Be aware that #first/#last won't guarantee order in this case.
|
|
267
|
-
#
|
|
268
|
-
# @param [ Hash ] opts The options for the query returning the first document.
|
|
269
|
-
#
|
|
270
|
-
# @option opts [ :none ] :id_sort Don't apply a sort on _id if no other sort
|
|
271
|
-
# is defined on the criteria.
|
|
272
|
-
#
|
|
273
|
-
# @return [ Document ] The first document.
|
|
274
|
-
#
|
|
275
|
-
# @since 3.0.0
|
|
276
|
-
def first(opts = {})
|
|
277
|
-
return documents.first if cached? && cache_loaded?
|
|
278
|
-
try_cache(:first) do
|
|
279
|
-
if sort = view.sort || ({ _id: 1 } unless opts[:id_sort] == :none)
|
|
280
|
-
if raw_doc = view.sort(sort).limit(1).first
|
|
281
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
|
282
|
-
eager_load([doc]).first
|
|
283
|
-
end
|
|
284
|
-
else
|
|
285
|
-
if raw_doc = view.limit(1).first
|
|
286
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
|
287
|
-
eager_load([doc]).first
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
end
|
|
292
|
-
alias :one :first
|
|
293
|
-
|
|
294
253
|
# Return the first result without applying sort
|
|
295
254
|
#
|
|
296
255
|
# @api private
|
|
297
|
-
#
|
|
298
|
-
# @since 4.0.2
|
|
299
256
|
def find_first
|
|
300
|
-
return documents.first if cached? && cache_loaded?
|
|
301
257
|
if raw_doc = view.first
|
|
302
258
|
doc = Factory.from_db(klass, raw_doc, criteria)
|
|
303
259
|
eager_load([doc]).first
|
|
304
260
|
end
|
|
305
261
|
end
|
|
306
262
|
|
|
307
|
-
# Execute a $geoNear command against the database.
|
|
308
|
-
#
|
|
309
|
-
# @example Find documents close to 10, 10.
|
|
310
|
-
# context.geo_near([ 10, 10 ])
|
|
311
|
-
#
|
|
312
|
-
# @example Find with spherical distance.
|
|
313
|
-
# context.geo_near([ 10, 10 ]).spherical
|
|
314
|
-
#
|
|
315
|
-
# @example Find with a max distance.
|
|
316
|
-
# context.geo_near([ 10, 10 ]).max_distance(0.5)
|
|
317
|
-
#
|
|
318
|
-
# @example Provide a distance multiplier.
|
|
319
|
-
# context.geo_near([ 10, 10 ]).distance_multiplier(1133)
|
|
320
|
-
#
|
|
321
|
-
# @param [ Array<Float> ] coordinates The coordinates.
|
|
322
|
-
#
|
|
323
|
-
# @return [ GeoNear ] The GeoNear command.
|
|
324
|
-
#
|
|
325
|
-
# @deprecated
|
|
326
|
-
#
|
|
327
|
-
# @since 3.1.0
|
|
328
|
-
def geo_near(coordinates)
|
|
329
|
-
GeoNear.new(collection, criteria, coordinates)
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
# Invoke the block for each element of Contextual. Create a new array
|
|
333
|
-
# containing the values returned by the block.
|
|
334
|
-
#
|
|
335
|
-
# If the symbol field name is passed instead of the block, additional
|
|
336
|
-
# optimizations would be used.
|
|
337
|
-
#
|
|
338
|
-
# @example Map by some field.
|
|
339
|
-
# context.map(:field1)
|
|
340
|
-
#
|
|
341
|
-
# @example Map with block.
|
|
342
|
-
# context.map(&:field1)
|
|
343
|
-
#
|
|
344
|
-
# @param [ Symbol ] field The field name.
|
|
345
|
-
#
|
|
346
|
-
# @return [ Array ] The result of mapping.
|
|
347
|
-
def map(field = nil, &block)
|
|
348
|
-
if block_given?
|
|
349
|
-
super(&block)
|
|
350
|
-
else
|
|
351
|
-
criteria.pluck(field)
|
|
352
|
-
end
|
|
353
|
-
end
|
|
354
|
-
|
|
355
263
|
# Create the new Mongo context. This delegates operations to the
|
|
356
264
|
# underlying driver.
|
|
357
265
|
#
|
|
@@ -359,10 +267,8 @@ module Mongoid
|
|
|
359
267
|
# Mongo.new(criteria)
|
|
360
268
|
#
|
|
361
269
|
# @param [ Criteria ] criteria The criteria.
|
|
362
|
-
#
|
|
363
|
-
# @since 3.0.0
|
|
364
270
|
def initialize(criteria)
|
|
365
|
-
@criteria, @klass
|
|
271
|
+
@criteria, @klass = criteria, criteria.klass
|
|
366
272
|
@collection = @klass.collection
|
|
367
273
|
criteria.send(:merge_type_selection)
|
|
368
274
|
@view = collection.find(criteria.selector, session: _session)
|
|
@@ -371,44 +277,15 @@ module Mongoid
|
|
|
371
277
|
|
|
372
278
|
def_delegator :@klass, :database_field_name
|
|
373
279
|
|
|
374
|
-
#
|
|
375
|
-
#
|
|
376
|
-
# @example Get the last document.
|
|
377
|
-
# context.last
|
|
378
|
-
#
|
|
379
|
-
# @note Automatically adding a sort on _id when no other sort is
|
|
380
|
-
# defined on the criteria has the potential to cause bad performance issues.
|
|
381
|
-
# If you experience unexpected poor performance when using #first or #last
|
|
382
|
-
# and have no sort defined on the criteria, use the option { id_sort: :none }.
|
|
383
|
-
# Be aware that #first/#last won't guarantee order in this case.
|
|
384
|
-
#
|
|
385
|
-
# @param [ Hash ] opts The options for the query returning the first document.
|
|
386
|
-
#
|
|
387
|
-
# @option opts [ :none ] :id_sort Don't apply a sort on _id if no other sort
|
|
388
|
-
# is defined on the criteria.
|
|
389
|
-
#
|
|
390
|
-
# @since 3.0.0
|
|
391
|
-
def last(opts = {})
|
|
392
|
-
try_cache(:last) do
|
|
393
|
-
with_inverse_sorting(opts) do
|
|
394
|
-
if raw_doc = view.limit(1).first
|
|
395
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
|
396
|
-
eager_load([doc]).first
|
|
397
|
-
end
|
|
398
|
-
end
|
|
399
|
-
end
|
|
400
|
-
end
|
|
401
|
-
|
|
402
|
-
# Get's the number of documents matching the query selector.
|
|
280
|
+
# Returns the number of documents in the database matching
|
|
281
|
+
# the query selector.
|
|
403
282
|
#
|
|
404
283
|
# @example Get the length.
|
|
405
284
|
# context.length
|
|
406
285
|
#
|
|
407
286
|
# @return [ Integer ] The number of documents.
|
|
408
|
-
#
|
|
409
|
-
# @since 3.0.0
|
|
410
287
|
def length
|
|
411
|
-
|
|
288
|
+
self.count
|
|
412
289
|
end
|
|
413
290
|
alias :size :length
|
|
414
291
|
|
|
@@ -420,8 +297,6 @@ module Mongoid
|
|
|
420
297
|
# @param [ Integer ] value The number of documents to return.
|
|
421
298
|
#
|
|
422
299
|
# @return [ Mongo ] The context.
|
|
423
|
-
#
|
|
424
|
-
# @since 3.0.0
|
|
425
300
|
def limit(value)
|
|
426
301
|
@view = view.limit(value) and self
|
|
427
302
|
end
|
|
@@ -435,40 +310,165 @@ module Mongoid
|
|
|
435
310
|
# @param [ String ] reduce The reduce js function.
|
|
436
311
|
#
|
|
437
312
|
# @return [ MapReduce ] The map/reduce lazy wrapper.
|
|
438
|
-
#
|
|
439
|
-
# @since 3.0.0
|
|
440
313
|
def map_reduce(map, reduce)
|
|
441
314
|
MapReduce.new(collection, criteria, map, reduce)
|
|
442
315
|
end
|
|
443
316
|
|
|
444
|
-
# Pluck the
|
|
445
|
-
#
|
|
317
|
+
# Pluck the field value(s) from the database. Returns one
|
|
318
|
+
# result for each document found in the database for
|
|
319
|
+
# the context. The results are normalized according to their
|
|
320
|
+
# Mongoid field types. Note that the results may include
|
|
321
|
+
# duplicates and nil values.
|
|
446
322
|
#
|
|
447
323
|
# @example Pluck a field.
|
|
448
324
|
# context.pluck(:_id)
|
|
449
325
|
#
|
|
450
|
-
# @
|
|
451
|
-
#
|
|
452
|
-
#
|
|
453
|
-
# @param [ String, Symbol, Array ] fields Fields to pluck.
|
|
454
|
-
#
|
|
455
|
-
# @return [ Array<Object, Array> ] The plucked values.
|
|
326
|
+
# @param [ [ String | Symbol ]... ] *fields Field(s) to pluck,
|
|
327
|
+
# which may include nested fields using dot-notation.
|
|
456
328
|
#
|
|
457
|
-
# @
|
|
329
|
+
# @return [ Array<Object> | Array<Array<Object>> ] The plucked values.
|
|
330
|
+
# If the *fields arg contains a single value, each result
|
|
331
|
+
# in the array will be a single value. Otherwise, each
|
|
332
|
+
# result in the array will be an array of values.
|
|
458
333
|
def pluck(*fields)
|
|
334
|
+
# Multiple fields can map to the same field name. For example, plucking
|
|
335
|
+
# a field and its _translations field map to the same field in the database.
|
|
336
|
+
# because of this, we need to keep track of the fields requested.
|
|
337
|
+
normalized_field_names = []
|
|
459
338
|
normalized_select = fields.inject({}) do |hash, f|
|
|
460
|
-
|
|
339
|
+
db_fn = klass.database_field_name(f)
|
|
340
|
+
normalized_field_names.push(db_fn)
|
|
341
|
+
hash[klass.cleanse_localized_field_names(f)] = true
|
|
461
342
|
hash
|
|
462
343
|
end
|
|
463
344
|
|
|
464
345
|
view.projection(normalized_select).reduce([]) do |plucked, doc|
|
|
465
|
-
values =
|
|
466
|
-
|
|
346
|
+
values = normalized_field_names.map do |n|
|
|
347
|
+
extract_value(doc, n)
|
|
467
348
|
end
|
|
468
349
|
plucked << (values.size == 1 ? values.first : values)
|
|
469
350
|
end
|
|
470
351
|
end
|
|
471
352
|
|
|
353
|
+
# Pick the single field values from the database.
|
|
354
|
+
#
|
|
355
|
+
# @example Pick a field.
|
|
356
|
+
# context.pick(:_id)
|
|
357
|
+
#
|
|
358
|
+
# @param [ [ String | Symbol ]... ] *fields Field(s) to pick.
|
|
359
|
+
#
|
|
360
|
+
# @return [ Object | Array<Object> ] The picked values.
|
|
361
|
+
def pick(*fields)
|
|
362
|
+
limit(1).pluck(*fields).first
|
|
363
|
+
end
|
|
364
|
+
|
|
365
|
+
# Take the given number of documents from the database.
|
|
366
|
+
#
|
|
367
|
+
# @example Take 10 documents
|
|
368
|
+
# context.take(10)
|
|
369
|
+
#
|
|
370
|
+
# @param [ Integer | nil ] limit The number of documents to return or nil.
|
|
371
|
+
#
|
|
372
|
+
# @return [ Document | Array<Document> ] The list of documents, or one
|
|
373
|
+
# document if no value was given.
|
|
374
|
+
def take(limit = nil)
|
|
375
|
+
if limit
|
|
376
|
+
limit(limit).to_a
|
|
377
|
+
else
|
|
378
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
|
379
|
+
# result is not sorted.
|
|
380
|
+
limit(1).to_a.first
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
# Take one document from the database and raise an error if there are none.
|
|
385
|
+
#
|
|
386
|
+
# @example Take a document
|
|
387
|
+
# context.take!
|
|
388
|
+
#
|
|
389
|
+
# @return [ Document ] The document.
|
|
390
|
+
#
|
|
391
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
392
|
+
# documents to take.
|
|
393
|
+
def take!
|
|
394
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
|
395
|
+
# result is not sorted.
|
|
396
|
+
if fst = limit(1).to_a.first
|
|
397
|
+
fst
|
|
398
|
+
else
|
|
399
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Get a hash of counts for the values of a single field. For example,
|
|
404
|
+
# if the following documents were in the database:
|
|
405
|
+
#
|
|
406
|
+
# { _id: 1, age: 21 }
|
|
407
|
+
# { _id: 2, age: 21 }
|
|
408
|
+
# { _id: 3, age: 22 }
|
|
409
|
+
#
|
|
410
|
+
# Model.tally("age")
|
|
411
|
+
#
|
|
412
|
+
# would yield the following result:
|
|
413
|
+
#
|
|
414
|
+
# { 21 => 2, 22 => 1 }
|
|
415
|
+
#
|
|
416
|
+
# When tallying a field inside an array or embeds_many association:
|
|
417
|
+
#
|
|
418
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 } ] }
|
|
419
|
+
# { _id: 2, array: [ { x: 1 }, { x: 2 } ] }
|
|
420
|
+
# { _id: 3, array: [ { x: 1 }, { x: 3 } ] }
|
|
421
|
+
#
|
|
422
|
+
# Model.tally("array.x")
|
|
423
|
+
#
|
|
424
|
+
# The keys of the resulting hash are arrays:
|
|
425
|
+
#
|
|
426
|
+
# { [ 1, 2 ] => 2, [ 1, 3 ] => 1 }
|
|
427
|
+
#
|
|
428
|
+
# Note that if tallying an element in an array of hashes, and the key
|
|
429
|
+
# doesn't exist in some of the hashes, tally will not include those
|
|
430
|
+
# nil keys in the resulting hash:
|
|
431
|
+
#
|
|
432
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 }, { y: 3 } ] }
|
|
433
|
+
#
|
|
434
|
+
# Model.tally("array.x")
|
|
435
|
+
# # => { [ 1, 2 ] => 1 }
|
|
436
|
+
#
|
|
437
|
+
# @param [ String | Symbol ] field The field name.
|
|
438
|
+
#
|
|
439
|
+
# @return [ Hash ] The hash of counts.
|
|
440
|
+
def tally(field)
|
|
441
|
+
name = klass.cleanse_localized_field_names(field)
|
|
442
|
+
|
|
443
|
+
fld = klass.traverse_association_tree(name)
|
|
444
|
+
pipeline = [ { "$group" => { _id: "$#{name}", counts: { "$sum": 1 } } } ]
|
|
445
|
+
pipeline.unshift("$match" => view.filter) unless view.filter.blank?
|
|
446
|
+
|
|
447
|
+
collection.aggregate(pipeline).reduce({}) do |tallies, doc|
|
|
448
|
+
is_translation = "#{name}_translations" == field.to_s
|
|
449
|
+
val = doc["_id"]
|
|
450
|
+
|
|
451
|
+
key = if val.is_a?(Array)
|
|
452
|
+
val.map do |v|
|
|
453
|
+
demongoize_with_field(fld, v, is_translation)
|
|
454
|
+
end
|
|
455
|
+
else
|
|
456
|
+
demongoize_with_field(fld, val, is_translation)
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
# The only time where a key will already exist in the tallies hash
|
|
460
|
+
# is when the values are stored differently in the database, but
|
|
461
|
+
# demongoize to the same value. A good example of when this happens
|
|
462
|
+
# is when using localized fields. While the server query won't group
|
|
463
|
+
# together hashes that have other values in different languages, the
|
|
464
|
+
# demongoized value is just the translation in the current locale,
|
|
465
|
+
# which can be the same across multiple of those unequal hashes.
|
|
466
|
+
tallies[key] ||= 0
|
|
467
|
+
tallies[key] += doc["counts"]
|
|
468
|
+
tallies
|
|
469
|
+
end
|
|
470
|
+
end
|
|
471
|
+
|
|
472
472
|
# Skips the provided number of documents.
|
|
473
473
|
#
|
|
474
474
|
# @example Skip the documents.
|
|
@@ -477,8 +477,6 @@ module Mongoid
|
|
|
477
477
|
# @param [ Integer ] value The number of documents to skip.
|
|
478
478
|
#
|
|
479
479
|
# @return [ Mongo ] The context.
|
|
480
|
-
#
|
|
481
|
-
# @since 3.0.0
|
|
482
480
|
def skip(value)
|
|
483
481
|
@view = view.skip(value) and self
|
|
484
482
|
end
|
|
@@ -492,8 +490,6 @@ module Mongoid
|
|
|
492
490
|
# pairs.
|
|
493
491
|
#
|
|
494
492
|
# @return [ Mongo ] The context.
|
|
495
|
-
#
|
|
496
|
-
# @since 3.0.0
|
|
497
493
|
def sort(values = nil, &block)
|
|
498
494
|
if block_given?
|
|
499
495
|
super(&block)
|
|
@@ -516,9 +512,7 @@ module Mongoid
|
|
|
516
512
|
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
|
517
513
|
# an update should apply.
|
|
518
514
|
#
|
|
519
|
-
# @return [ nil
|
|
520
|
-
#
|
|
521
|
-
# @since 3.0.0
|
|
515
|
+
# @return [ nil | false ] False if no attributes were provided.
|
|
522
516
|
def update(attributes = nil, opts = {})
|
|
523
517
|
update_documents(attributes, :update_one, opts)
|
|
524
518
|
end
|
|
@@ -534,33 +528,257 @@ module Mongoid
|
|
|
534
528
|
# @option opts [ Array ] :array_filters A set of filters specifying to which array elements
|
|
535
529
|
# an update should apply.
|
|
536
530
|
#
|
|
537
|
-
# @return [ nil
|
|
538
|
-
#
|
|
539
|
-
# @since 3.0.0
|
|
531
|
+
# @return [ nil | false ] False if no attributes were provided.
|
|
540
532
|
def update_all(attributes = nil, opts = {})
|
|
541
533
|
update_documents(attributes, :update_many, opts)
|
|
542
534
|
end
|
|
543
535
|
|
|
544
|
-
|
|
536
|
+
# Get the first document in the database for the criteria's selector.
|
|
537
|
+
#
|
|
538
|
+
# @example Get the first document.
|
|
539
|
+
# context.first
|
|
540
|
+
#
|
|
541
|
+
# @note Automatically adding a sort on _id when no other sort is
|
|
542
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
|
543
|
+
# If you experience unexpected poor performance when using #first or #last
|
|
544
|
+
# and have no sort defined on the criteria, use #take instead.
|
|
545
|
+
# Be aware that #take won't guarantee order.
|
|
546
|
+
#
|
|
547
|
+
# @param [ Integer ] limit The number of documents to return.
|
|
548
|
+
#
|
|
549
|
+
# @return [ Document | nil ] The first document or nil if none is found.
|
|
550
|
+
def first(limit = nil)
|
|
551
|
+
if limit.nil?
|
|
552
|
+
retrieve_nth(0)
|
|
553
|
+
else
|
|
554
|
+
retrieve_nth_with_limit(0, limit)
|
|
555
|
+
end
|
|
556
|
+
end
|
|
557
|
+
alias :one :first
|
|
545
558
|
|
|
546
|
-
#
|
|
559
|
+
# Get the first document in the database for the criteria's selector or
|
|
560
|
+
# raise an error if none is found.
|
|
561
|
+
#
|
|
562
|
+
# @example Get the first document.
|
|
563
|
+
# context.first!
|
|
564
|
+
#
|
|
565
|
+
# @note Automatically adding a sort on _id when no other sort is
|
|
566
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
|
567
|
+
# If you experience unexpected poor performance when using #first! or #last!
|
|
568
|
+
# and have no sort defined on the criteria, use #take! instead.
|
|
569
|
+
# Be aware that #take! won't guarantee order.
|
|
547
570
|
#
|
|
548
|
-
# @
|
|
571
|
+
# @return [ Document ] The first document.
|
|
549
572
|
#
|
|
550
|
-
# @
|
|
573
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
574
|
+
# documents available.
|
|
575
|
+
def first!
|
|
576
|
+
first || raise_document_not_found_error
|
|
577
|
+
end
|
|
578
|
+
|
|
579
|
+
# Get the last document in the database for the criteria's selector.
|
|
551
580
|
#
|
|
552
|
-
# @
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
581
|
+
# @example Get the last document.
|
|
582
|
+
# context.last
|
|
583
|
+
#
|
|
584
|
+
# @note Automatically adding a sort on _id when no other sort is
|
|
585
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
|
586
|
+
# If you experience unexpected poor performance when using #first or #last
|
|
587
|
+
# and have no sort defined on the criteria, use #take instead.
|
|
588
|
+
# Be aware that #take won't guarantee order.
|
|
589
|
+
#
|
|
590
|
+
# @param [ Integer ] limit The number of documents to return.
|
|
591
|
+
#
|
|
592
|
+
# @return [ Document | nil ] The last document or nil if none is found.
|
|
593
|
+
def last(limit = nil)
|
|
594
|
+
if limit.nil?
|
|
595
|
+
retrieve_nth_to_last(0)
|
|
556
596
|
else
|
|
557
|
-
|
|
558
|
-
instance_variable_set("@#{key}", ret = yield)
|
|
559
|
-
end
|
|
560
|
-
ret
|
|
597
|
+
retrieve_nth_to_last_with_limit(0, limit)
|
|
561
598
|
end
|
|
562
599
|
end
|
|
563
600
|
|
|
601
|
+
# Get the last document in the database for the criteria's selector or
|
|
602
|
+
# raise an error if none is found.
|
|
603
|
+
#
|
|
604
|
+
# @example Get the last document.
|
|
605
|
+
# context.last!
|
|
606
|
+
#
|
|
607
|
+
# @note Automatically adding a sort on _id when no other sort is
|
|
608
|
+
# defined on the criteria has the potential to cause bad performance issues.
|
|
609
|
+
# If you experience unexpected poor performance when using #first! or #last!
|
|
610
|
+
# and have no sort defined on the criteria, use #take! instead.
|
|
611
|
+
# Be aware that #take! won't guarantee order.
|
|
612
|
+
#
|
|
613
|
+
# @return [ Document ] The last document.
|
|
614
|
+
#
|
|
615
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
616
|
+
# documents available.
|
|
617
|
+
def last!
|
|
618
|
+
last || raise_document_not_found_error
|
|
619
|
+
end
|
|
620
|
+
|
|
621
|
+
# Get the second document in the database for the criteria's selector.
|
|
622
|
+
#
|
|
623
|
+
# @example Get the second document.
|
|
624
|
+
# context.second
|
|
625
|
+
#
|
|
626
|
+
# @return [ Document | nil ] The second document or nil if none is found.
|
|
627
|
+
def second
|
|
628
|
+
retrieve_nth(1)
|
|
629
|
+
end
|
|
630
|
+
|
|
631
|
+
# Get the second document in the database for the criteria's selector or
|
|
632
|
+
# raise an error if none is found.
|
|
633
|
+
#
|
|
634
|
+
# @example Get the second document.
|
|
635
|
+
# context.second!
|
|
636
|
+
#
|
|
637
|
+
# @return [ Document ] The second document.
|
|
638
|
+
#
|
|
639
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
640
|
+
# documents available.
|
|
641
|
+
def second!
|
|
642
|
+
second || raise_document_not_found_error
|
|
643
|
+
end
|
|
644
|
+
|
|
645
|
+
# Get the third document in the database for the criteria's selector.
|
|
646
|
+
#
|
|
647
|
+
# @example Get the third document.
|
|
648
|
+
# context.third
|
|
649
|
+
#
|
|
650
|
+
# @return [ Document | nil ] The third document or nil if none is found.
|
|
651
|
+
def third
|
|
652
|
+
retrieve_nth(2)
|
|
653
|
+
end
|
|
654
|
+
|
|
655
|
+
# Get the third document in the database for the criteria's selector or
|
|
656
|
+
# raise an error if none is found.
|
|
657
|
+
#
|
|
658
|
+
# @example Get the third document.
|
|
659
|
+
# context.third!
|
|
660
|
+
#
|
|
661
|
+
# @return [ Document ] The third document.
|
|
662
|
+
#
|
|
663
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
664
|
+
# documents available.
|
|
665
|
+
def third!
|
|
666
|
+
third || raise_document_not_found_error
|
|
667
|
+
end
|
|
668
|
+
|
|
669
|
+
# Get the fourth document in the database for the criteria's selector.
|
|
670
|
+
#
|
|
671
|
+
# @example Get the fourth document.
|
|
672
|
+
# context.fourth
|
|
673
|
+
#
|
|
674
|
+
# @return [ Document | nil ] The fourth document or nil if none is found.
|
|
675
|
+
def fourth
|
|
676
|
+
retrieve_nth(3)
|
|
677
|
+
end
|
|
678
|
+
|
|
679
|
+
# Get the fourth document in the database for the criteria's selector or
|
|
680
|
+
# raise an error if none is found.
|
|
681
|
+
#
|
|
682
|
+
# @example Get the fourth document.
|
|
683
|
+
# context.fourth!
|
|
684
|
+
#
|
|
685
|
+
# @return [ Document ] The fourth document.
|
|
686
|
+
#
|
|
687
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
688
|
+
# documents available.
|
|
689
|
+
def fourth!
|
|
690
|
+
fourth || raise_document_not_found_error
|
|
691
|
+
end
|
|
692
|
+
|
|
693
|
+
# Get the fifth document in the database for the criteria's selector.
|
|
694
|
+
#
|
|
695
|
+
# @example Get the fifth document.
|
|
696
|
+
# context.fifth
|
|
697
|
+
#
|
|
698
|
+
# @return [ Document | nil ] The fifth document or nil if none is found.
|
|
699
|
+
def fifth
|
|
700
|
+
retrieve_nth(4)
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
# Get the fifth document in the database for the criteria's selector or
|
|
704
|
+
# raise an error if none is found.
|
|
705
|
+
#
|
|
706
|
+
# @example Get the fifth document.
|
|
707
|
+
# context.fifth!
|
|
708
|
+
#
|
|
709
|
+
# @return [ Document ] The fifth document.
|
|
710
|
+
#
|
|
711
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
712
|
+
# documents available.
|
|
713
|
+
def fifth!
|
|
714
|
+
fifth || raise_document_not_found_error
|
|
715
|
+
end
|
|
716
|
+
|
|
717
|
+
# Get the second to last document in the database for the criteria's
|
|
718
|
+
# selector.
|
|
719
|
+
#
|
|
720
|
+
# @example Get the second to last document.
|
|
721
|
+
# context.second_to_last
|
|
722
|
+
#
|
|
723
|
+
# @return [ Document | nil ] The second to last document or nil if none
|
|
724
|
+
# is found.
|
|
725
|
+
def second_to_last
|
|
726
|
+
retrieve_nth_to_last(1)
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
# Get the second to last document in the database for the criteria's
|
|
730
|
+
# selector or raise an error if none is found.
|
|
731
|
+
#
|
|
732
|
+
# @example Get the second to last document.
|
|
733
|
+
# context.second_to_last!
|
|
734
|
+
#
|
|
735
|
+
# @return [ Document ] The second to last document.
|
|
736
|
+
#
|
|
737
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
738
|
+
# documents available.
|
|
739
|
+
def second_to_last!
|
|
740
|
+
second_to_last || raise_document_not_found_error
|
|
741
|
+
end
|
|
742
|
+
|
|
743
|
+
# Get the third to last document in the database for the criteria's
|
|
744
|
+
# selector.
|
|
745
|
+
#
|
|
746
|
+
# @example Get the third to last document.
|
|
747
|
+
# context.third_to_last
|
|
748
|
+
#
|
|
749
|
+
# @return [ Document | nil ] The third to last document or nil if none
|
|
750
|
+
# is found.
|
|
751
|
+
def third_to_last
|
|
752
|
+
retrieve_nth_to_last(2)
|
|
753
|
+
end
|
|
754
|
+
|
|
755
|
+
# Get the third 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 third to last document.
|
|
759
|
+
# context.third_to_last!
|
|
760
|
+
#
|
|
761
|
+
# @return [ Document ] The third to last document.
|
|
762
|
+
#
|
|
763
|
+
# @raise [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
|
764
|
+
# documents available.
|
|
765
|
+
def third_to_last!
|
|
766
|
+
third_to_last || raise_document_not_found_error
|
|
767
|
+
end
|
|
768
|
+
|
|
769
|
+
# Schedule a task to load documents for the context.
|
|
770
|
+
#
|
|
771
|
+
# Depending on the Mongoid configuration, the scheduled task can be executed
|
|
772
|
+
# immediately on the caller's thread, or can be scheduled for an
|
|
773
|
+
# asynchronous execution.
|
|
774
|
+
#
|
|
775
|
+
# @api private
|
|
776
|
+
def load_async
|
|
777
|
+
@documents_loader ||= DocumentsLoader.new(view, klass, criteria)
|
|
778
|
+
end
|
|
779
|
+
|
|
780
|
+
private
|
|
781
|
+
|
|
564
782
|
# Update the documents for the provided method.
|
|
565
783
|
#
|
|
566
784
|
# @api private
|
|
@@ -571,13 +789,11 @@ module Mongoid
|
|
|
571
789
|
# @param [ Hash ] attributes The updates.
|
|
572
790
|
# @param [ Symbol ] method The method to use.
|
|
573
791
|
#
|
|
574
|
-
# @return [ true
|
|
575
|
-
#
|
|
576
|
-
# @since 3.0.4
|
|
792
|
+
# @return [ true | false ] If the update succeeded.
|
|
577
793
|
def update_documents(attributes, method = :update_one, opts = {})
|
|
578
794
|
return false unless attributes
|
|
579
|
-
|
|
580
|
-
view.send(method,
|
|
795
|
+
|
|
796
|
+
view.send(method, AtomicUpdatePreparer.prepare(attributes, klass), opts)
|
|
581
797
|
end
|
|
582
798
|
|
|
583
799
|
# Apply the field limitations.
|
|
@@ -586,8 +802,6 @@ module Mongoid
|
|
|
586
802
|
#
|
|
587
803
|
# @example Apply the field limitations.
|
|
588
804
|
# context.apply_fields
|
|
589
|
-
#
|
|
590
|
-
# @since 3.0.0
|
|
591
805
|
def apply_fields
|
|
592
806
|
if spec = criteria.options[:fields]
|
|
593
807
|
@view = view.projection(spec)
|
|
@@ -600,8 +814,6 @@ module Mongoid
|
|
|
600
814
|
#
|
|
601
815
|
# @example Apply all options.
|
|
602
816
|
# context.apply_options
|
|
603
|
-
#
|
|
604
|
-
# @since 3.1.0
|
|
605
817
|
def apply_options
|
|
606
818
|
apply_fields
|
|
607
819
|
OPTIONS.each do |name|
|
|
@@ -618,8 +830,6 @@ module Mongoid
|
|
|
618
830
|
#
|
|
619
831
|
# @example Apply the skip option.
|
|
620
832
|
# context.apply_option(:skip)
|
|
621
|
-
#
|
|
622
|
-
# @since 3.1.0
|
|
623
833
|
def apply_option(name)
|
|
624
834
|
if spec = criteria.options[name]
|
|
625
835
|
@view = view.send(name, spec)
|
|
@@ -629,115 +839,234 @@ module Mongoid
|
|
|
629
839
|
# Map the inverse sort symbols to the correct MongoDB values.
|
|
630
840
|
#
|
|
631
841
|
# @api private
|
|
842
|
+
def inverse_sorting
|
|
843
|
+
sort = view.sort || { _id: 1 }
|
|
844
|
+
Hash[sort.map{|k, v| [k, -1*v]}]
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
# Get the documents the context should iterate.
|
|
848
|
+
#
|
|
849
|
+
# If the documents have been already preloaded by `Document::Loader`
|
|
850
|
+
# instance, they will be used.
|
|
632
851
|
#
|
|
633
|
-
# @
|
|
634
|
-
# context.with_inverse_sorting
|
|
852
|
+
# @return [ Array<Document> | Mongo::Collection::View ] The docs to iterate.
|
|
635
853
|
#
|
|
636
|
-
# @
|
|
637
|
-
def
|
|
638
|
-
|
|
639
|
-
if
|
|
640
|
-
@
|
|
854
|
+
# @api private
|
|
855
|
+
def documents_for_iteration
|
|
856
|
+
if @documents_loader
|
|
857
|
+
if @documents_loader.started?
|
|
858
|
+
@documents_loader.value!
|
|
859
|
+
else
|
|
860
|
+
@documents_loader.unschedule
|
|
861
|
+
@documents_loader.execute
|
|
641
862
|
end
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
863
|
+
else
|
|
864
|
+
return view unless eager_loadable?
|
|
865
|
+
docs = view.map do |doc|
|
|
866
|
+
Factory.from_db(klass, doc, criteria)
|
|
867
|
+
end
|
|
868
|
+
eager_load(docs)
|
|
645
869
|
end
|
|
646
870
|
end
|
|
647
871
|
|
|
648
|
-
#
|
|
872
|
+
# Yield to the document.
|
|
649
873
|
#
|
|
650
874
|
# @api private
|
|
651
875
|
#
|
|
652
|
-
# @example
|
|
653
|
-
# context.
|
|
654
|
-
#
|
|
655
|
-
#
|
|
876
|
+
# @example Yield the document.
|
|
877
|
+
# context.yield_document(doc) do |doc|
|
|
878
|
+
# ...
|
|
879
|
+
# end
|
|
656
880
|
#
|
|
657
|
-
# @
|
|
658
|
-
def
|
|
659
|
-
|
|
881
|
+
# @param [ Document ] document The document to yield to.
|
|
882
|
+
def yield_document(document, &block)
|
|
883
|
+
doc = document.respond_to?(:_id) ?
|
|
884
|
+
document : Factory.from_db(klass, document, criteria)
|
|
885
|
+
yield(doc)
|
|
660
886
|
end
|
|
661
887
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
#
|
|
665
|
-
# @api private
|
|
666
|
-
#
|
|
667
|
-
# @example Is the cache loaded?
|
|
668
|
-
# context.cache_loaded?
|
|
669
|
-
#
|
|
670
|
-
# @return [ true, false ] If the cache is loaded.
|
|
671
|
-
#
|
|
672
|
-
# @since 3.0.0
|
|
673
|
-
def cache_loaded?
|
|
674
|
-
!!@cache_loaded
|
|
888
|
+
def _session
|
|
889
|
+
@criteria.send(:_session)
|
|
675
890
|
end
|
|
676
891
|
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
# @api private
|
|
680
|
-
#
|
|
681
|
-
# @example Get the cached documents.
|
|
682
|
-
# context.documents
|
|
683
|
-
#
|
|
684
|
-
# @return [ Array<Document> ] The documents.
|
|
685
|
-
#
|
|
686
|
-
# @since 3.0.0
|
|
687
|
-
def documents
|
|
688
|
-
@documents ||= []
|
|
892
|
+
def acknowledged_write?
|
|
893
|
+
collection.write_concern.nil? || collection.write_concern.acknowledged?
|
|
689
894
|
end
|
|
690
895
|
|
|
691
|
-
#
|
|
896
|
+
# Fetch the element from the given hash and demongoize it using the
|
|
897
|
+
# given field. If the obj is an array, map over it and call this method
|
|
898
|
+
# on all of its elements.
|
|
692
899
|
#
|
|
693
|
-
#
|
|
694
|
-
#
|
|
695
|
-
#
|
|
696
|
-
# those.
|
|
697
|
-
# 3. Use the query.
|
|
900
|
+
# @param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from.
|
|
901
|
+
# @param [ String ] meth The key to fetch from the hash.
|
|
902
|
+
# @param [ Field ] field The field to use for demongoization.
|
|
698
903
|
#
|
|
699
|
-
# @
|
|
904
|
+
# @return [ Object ] The demongoized value.
|
|
700
905
|
#
|
|
701
|
-
# @
|
|
702
|
-
|
|
906
|
+
# @api private
|
|
907
|
+
def fetch_and_demongoize(obj, meth, field)
|
|
908
|
+
if obj.is_a?(Array)
|
|
909
|
+
obj.map { |doc| fetch_and_demongoize(doc, meth, field) }
|
|
910
|
+
else
|
|
911
|
+
res = obj.try(:fetch, meth, nil)
|
|
912
|
+
field ? field.demongoize(res) : res.class.demongoize(res)
|
|
913
|
+
end
|
|
914
|
+
end
|
|
915
|
+
|
|
916
|
+
# Extracts the value for the given field name from the given attribute
|
|
917
|
+
# hash.
|
|
703
918
|
#
|
|
704
|
-
# @
|
|
919
|
+
# @param [ Hash ] attrs The attributes hash.
|
|
920
|
+
# @param [ String ] field_name The name of the field to extract.
|
|
705
921
|
#
|
|
706
|
-
# @
|
|
707
|
-
def
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
922
|
+
# @param [ Object ] The value for the given field name
|
|
923
|
+
def extract_value(attrs, field_name)
|
|
924
|
+
i = 1
|
|
925
|
+
num_meths = field_name.count('.') + 1
|
|
926
|
+
curr = attrs.dup
|
|
927
|
+
|
|
928
|
+
klass.traverse_association_tree(field_name) do |meth, obj, is_field|
|
|
929
|
+
field = obj if is_field
|
|
930
|
+
is_translation = false
|
|
931
|
+
# If no association or field was found, check if the meth is an
|
|
932
|
+
# _translations field.
|
|
933
|
+
if obj.nil? & tr = meth.match(/(.*)_translations\z/)&.captures&.first
|
|
934
|
+
is_translation = true
|
|
935
|
+
meth = tr
|
|
936
|
+
end
|
|
937
|
+
|
|
938
|
+
# 1. If curr is an array fetch from all elements in the array.
|
|
939
|
+
# 2. If the field is localized, and is not an _translations field
|
|
940
|
+
# (_translations fields don't show up in the fields hash).
|
|
941
|
+
# - If this is the end of the methods, return the translation for
|
|
942
|
+
# the current locale.
|
|
943
|
+
# - Otherwise, return the whole translations hash so the next method
|
|
944
|
+
# can select the language it wants.
|
|
945
|
+
# 3. If the meth is an _translations field, do not demongoize the
|
|
946
|
+
# value so the full hash is returned.
|
|
947
|
+
# 4. Otherwise, fetch and demongoize the value for the key meth.
|
|
948
|
+
curr = if curr.is_a? Array
|
|
949
|
+
res = fetch_and_demongoize(curr, meth, field)
|
|
950
|
+
res.empty? ? nil : res
|
|
951
|
+
elsif !is_translation && field&.localized?
|
|
952
|
+
if i < num_meths
|
|
953
|
+
curr.try(:fetch, meth, nil)
|
|
954
|
+
else
|
|
955
|
+
fetch_and_demongoize(curr, meth, field)
|
|
956
|
+
end
|
|
957
|
+
elsif is_translation
|
|
958
|
+
curr.try(:fetch, meth, nil)
|
|
959
|
+
else
|
|
960
|
+
fetch_and_demongoize(curr, meth, field)
|
|
961
|
+
end
|
|
962
|
+
|
|
963
|
+
i += 1
|
|
964
|
+
end
|
|
965
|
+
curr
|
|
712
966
|
end
|
|
713
967
|
|
|
714
|
-
#
|
|
968
|
+
# Recursively demongoize the given value. This method recursively traverses
|
|
969
|
+
# the class tree to find the correct field to use to demongoize the value.
|
|
970
|
+
#
|
|
971
|
+
# @param [ String ] field_name The name of the field to demongoize.
|
|
972
|
+
# @param [ Object ] value The value to demongoize.
|
|
973
|
+
# @param [ true | false ] is_translation The field we are retrieving is an
|
|
974
|
+
# _translations field.
|
|
975
|
+
#
|
|
976
|
+
# @return [ Object ] The demongoized value.
|
|
977
|
+
def recursive_demongoize(field_name, value, is_translation)
|
|
978
|
+
field = klass.traverse_association_tree(field_name)
|
|
979
|
+
demongoize_with_field(field, value, is_translation)
|
|
980
|
+
end
|
|
981
|
+
|
|
982
|
+
# Demongoize the value for the given field. If the field is nil or the
|
|
983
|
+
# field is a translations field, the value is demongoized using its class.
|
|
715
984
|
#
|
|
716
|
-
# @
|
|
985
|
+
# @param [ Field ] field The field to use to demongoize.
|
|
986
|
+
# @param [ Object ] value The value to demongoize.
|
|
987
|
+
# @param [ true | false ] is_translation The field we are retrieving is an
|
|
988
|
+
# _translations field.
|
|
717
989
|
#
|
|
718
|
-
# @
|
|
719
|
-
# context.yield_document(doc) do |doc|
|
|
720
|
-
# ...
|
|
721
|
-
# end
|
|
990
|
+
# @return [ Object ] The demongoized value.
|
|
722
991
|
#
|
|
723
|
-
# @
|
|
992
|
+
# @api private
|
|
993
|
+
def demongoize_with_field(field, value, is_translation)
|
|
994
|
+
if field
|
|
995
|
+
# If it's a localized field that's not a hash, don't demongoize
|
|
996
|
+
# again, we already have the translation. If it's an _translations
|
|
997
|
+
# field, don't demongoize, we want the full hash not just a
|
|
998
|
+
# specific translation.
|
|
999
|
+
# If it is a hash, and it's not a translations field, we need to
|
|
1000
|
+
# demongoize to get the correct translation.
|
|
1001
|
+
if field.localized? && (!value.is_a?(Hash) || is_translation)
|
|
1002
|
+
value.class.demongoize(value)
|
|
1003
|
+
else
|
|
1004
|
+
field.demongoize(value)
|
|
1005
|
+
end
|
|
1006
|
+
else
|
|
1007
|
+
value.class.demongoize(value)
|
|
1008
|
+
end
|
|
1009
|
+
end
|
|
1010
|
+
|
|
1011
|
+
# Process the raw documents retrieved for #first/#last.
|
|
724
1012
|
#
|
|
725
|
-
# @
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
1013
|
+
# @return [ Array<Document> | Document ] The list of documents or a
|
|
1014
|
+
# single document.
|
|
1015
|
+
def process_raw_docs(raw_docs, limit)
|
|
1016
|
+
docs = raw_docs.map do |d|
|
|
1017
|
+
Factory.from_db(klass, d, criteria)
|
|
1018
|
+
end
|
|
1019
|
+
docs = eager_load(docs)
|
|
1020
|
+
limit ? docs : docs.first
|
|
731
1021
|
end
|
|
732
1022
|
|
|
733
|
-
|
|
1023
|
+
# Queries whether the current context is valid for use with
|
|
1024
|
+
# the #count_documents? predicate. A context is valid if it
|
|
1025
|
+
# does not include a `$where` operator.
|
|
1026
|
+
#
|
|
1027
|
+
# @return [ true | false ] whether or not the current context
|
|
1028
|
+
# excludes a `$where` operator.
|
|
1029
|
+
#
|
|
1030
|
+
# TODO: Remove this method when we remove the deprecated for_js API.
|
|
1031
|
+
# https://jira.mongodb.org/browse/MONGOID-5681
|
|
1032
|
+
def valid_for_count_documents?(hash = view.filter)
|
|
1033
|
+
# Note that `view.filter` is a BSON::Document, and all keys in a
|
|
1034
|
+
# BSON::Document are strings; we don't need to worry about symbol
|
|
1035
|
+
# representations of `$where`.
|
|
1036
|
+
hash.keys.each do |key|
|
|
1037
|
+
return false if key == '$where'
|
|
1038
|
+
return false if hash[key].is_a?(Hash) && !valid_for_count_documents?(hash[key])
|
|
1039
|
+
end
|
|
734
1040
|
|
|
735
|
-
|
|
736
|
-
@criteria.send(:_session)
|
|
1041
|
+
true
|
|
737
1042
|
end
|
|
738
1043
|
|
|
739
|
-
def
|
|
740
|
-
|
|
1044
|
+
def raise_document_not_found_error
|
|
1045
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
|
1046
|
+
end
|
|
1047
|
+
|
|
1048
|
+
def retrieve_nth(n)
|
|
1049
|
+
retrieve_nth_with_limit(n, 1).first
|
|
1050
|
+
end
|
|
1051
|
+
|
|
1052
|
+
def retrieve_nth_with_limit(n, limit)
|
|
1053
|
+
sort = view.sort || { _id: 1 }
|
|
1054
|
+
v = view.sort(sort).limit(limit || 1)
|
|
1055
|
+
v = v.skip(n) if n > 0
|
|
1056
|
+
if raw_docs = v.to_a
|
|
1057
|
+
process_raw_docs(raw_docs, limit)
|
|
1058
|
+
end
|
|
1059
|
+
end
|
|
1060
|
+
|
|
1061
|
+
def retrieve_nth_to_last(n)
|
|
1062
|
+
retrieve_nth_to_last_with_limit(n, 1).first
|
|
1063
|
+
end
|
|
1064
|
+
|
|
1065
|
+
def retrieve_nth_to_last_with_limit(n, limit)
|
|
1066
|
+
v = view.sort(inverse_sorting).skip(n).limit(limit || 1)
|
|
1067
|
+
v = v.skip(n) if n > 0
|
|
1068
|
+
raw_docs = v.to_a.reverse
|
|
1069
|
+
process_raw_docs(raw_docs, limit)
|
|
741
1070
|
end
|
|
742
1071
|
end
|
|
743
1072
|
end
|