mongoid 9.0.11 → 9.1.1
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
- data/CHANGELOG.md +8 -8
- data/README.md +5 -11
- data/Rakefile +35 -38
- data/lib/config/locales/en.yml +60 -0
- data/lib/mongoid/association/accessors.rb +27 -26
- data/lib/mongoid/association/bindable.rb +43 -45
- data/lib/mongoid/association/builders.rb +18 -15
- data/lib/mongoid/association/constrainable.rb +3 -5
- data/lib/mongoid/association/depending.rb +43 -43
- data/lib/mongoid/association/eager.rb +56 -13
- data/lib/mongoid/association/eager_load/discriminated_inclusion.rb +88 -0
- data/lib/mongoid/association/eager_load/embedded_distributor.rb +151 -0
- data/lib/mongoid/association/eager_load/inclusion.rb +173 -0
- data/lib/mongoid/association/eager_load/inclusion_tree.rb +96 -0
- data/lib/mongoid/association/eager_load/lookup_pipeline.rb +121 -0
- data/lib/mongoid/association/eager_load/polymorphic_preloader.rb +61 -0
- data/lib/mongoid/association/eager_load/polymorphic_targets.rb +151 -0
- data/lib/mongoid/association/eager_loadable.rb +108 -23
- data/lib/mongoid/association/embedded/batchable.rb +28 -30
- data/lib/mongoid/association/embedded/cyclic.rb +8 -11
- data/lib/mongoid/association/embedded/eager.rb +1 -6
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +6 -9
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -3
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -0
- data/lib/mongoid/association/embedded/embedded_in.rb +25 -22
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +0 -2
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +2 -3
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +7 -2
- data/lib/mongoid/association/embedded/embeds_many.rb +24 -21
- data/lib/mongoid/association/embedded/embeds_one/binding.rb +0 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +2 -6
- data/lib/mongoid/association/embedded/embeds_one.rb +21 -18
- data/lib/mongoid/association/embedded.rb +0 -1
- data/lib/mongoid/association/macros.rb +16 -8
- data/lib/mongoid/association/many.rb +75 -3
- data/lib/mongoid/association/marshalable.rb +0 -3
- data/lib/mongoid/association/nested/many.rb +52 -18
- data/lib/mongoid/association/nested/nested_buildable.rb +20 -9
- data/lib/mongoid/association/nested/one.rb +10 -8
- data/lib/mongoid/association/nested.rb +1 -3
- data/lib/mongoid/association/one.rb +0 -3
- data/lib/mongoid/association/options.rb +25 -7
- data/lib/mongoid/association/referenced/auto_save.rb +0 -2
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +11 -15
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +23 -5
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +7 -4
- data/lib/mongoid/association/referenced/belongs_to.rb +49 -43
- data/lib/mongoid/association/referenced/counter_cache.rb +7 -12
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +0 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +8 -4
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +0 -3
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +57 -47
- data/lib/mongoid/association/referenced/has_many/binding.rb +0 -2
- data/lib/mongoid/association/referenced/has_many/buildable.rb +11 -5
- data/lib/mongoid/association/referenced/has_many/eager.rb +0 -3
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +109 -38
- data/lib/mongoid/association/referenced/has_many/proxy.rb +110 -7
- data/lib/mongoid/association/referenced/has_many.rb +30 -24
- data/lib/mongoid/association/referenced/has_many_through/eager.rb +99 -0
- data/lib/mongoid/association/referenced/has_many_through/proxy.rb +68 -0
- data/lib/mongoid/association/referenced/has_many_through.rb +201 -0
- data/lib/mongoid/association/referenced/has_one/binding.rb +0 -2
- data/lib/mongoid/association/referenced/has_one/buildable.rb +11 -9
- data/lib/mongoid/association/referenced/has_one/eager.rb +0 -3
- data/lib/mongoid/association/referenced/has_one.rb +27 -21
- data/lib/mongoid/association/referenced/has_one_through/eager.rb +65 -0
- data/lib/mongoid/association/referenced/has_one_through/proxy.rb +30 -0
- data/lib/mongoid/association/referenced/has_one_through.rb +167 -0
- data/lib/mongoid/association/referenced/syncable.rb +30 -34
- data/lib/mongoid/association/referenced.rb +2 -1
- data/lib/mongoid/association/reflections.rb +0 -3
- data/lib/mongoid/association/relatable.rb +108 -65
- data/lib/mongoid/association.rb +19 -15
- data/lib/mongoid/atomic/modifiers.rb +65 -25
- data/lib/mongoid/atomic/paths/embedded/many.rb +4 -7
- data/lib/mongoid/atomic/paths/embedded/one.rb +2 -4
- data/lib/mongoid/atomic/paths/embedded.rb +3 -6
- data/lib/mongoid/atomic/paths/root.rb +1 -4
- data/lib/mongoid/atomic/paths.rb +2 -3
- data/lib/mongoid/atomic.rb +0 -3
- data/lib/mongoid/attributes/dynamic.rb +6 -7
- data/lib/mongoid/attributes/nested.rb +8 -10
- data/lib/mongoid/attributes/projector.rb +7 -20
- data/lib/mongoid/attributes/readonly.rb +6 -11
- data/lib/mongoid/attributes.rb +18 -34
- data/lib/mongoid/cacheable.rb +24 -6
- data/lib/mongoid/clients/factory.rb +13 -22
- data/lib/mongoid/clients/options.rb +2 -5
- data/lib/mongoid/clients/sessions.rb +50 -60
- data/lib/mongoid/clients/storage_options.rb +1 -4
- data/lib/mongoid/clients/validators/storage.rb +2 -3
- data/lib/mongoid/clients/validators.rb +1 -2
- data/lib/mongoid/clients.rb +8 -11
- data/lib/mongoid/collection_configurable.rb +18 -14
- data/lib/mongoid/composable.rb +30 -34
- data/lib/mongoid/config/defaults.rb +6 -4
- data/lib/mongoid/config/encryption.rb +36 -21
- data/lib/mongoid/config/environment.rb +7 -16
- data/lib/mongoid/config/introspection.rb +14 -16
- data/lib/mongoid/config/options.rb +16 -10
- data/lib/mongoid/config/validators/async_query_executor.rb +3 -6
- data/lib/mongoid/config/validators/client.rb +12 -15
- data/lib/mongoid/config/validators/option.rb +3 -5
- data/lib/mongoid/config/validators.rb +3 -4
- data/lib/mongoid/config.rb +188 -47
- data/lib/mongoid/contextual/aggregable/memory.rb +7 -5
- data/lib/mongoid/contextual/aggregable/mongo.rb +20 -22
- data/lib/mongoid/contextual/aggregable/none.rb +2 -4
- data/lib/mongoid/contextual/aggregable.rb +5 -7
- data/lib/mongoid/contextual/atomic.rb +20 -24
- data/lib/mongoid/contextual/command.rb +0 -3
- data/lib/mongoid/contextual/map_reduce.rb +12 -16
- data/lib/mongoid/contextual/memory.rb +87 -69
- data/lib/mongoid/contextual/mongo/documents_loader.rb +2 -3
- data/lib/mongoid/contextual/mongo.rb +169 -85
- data/lib/mongoid/contextual/none.rb +9 -9
- data/lib/mongoid/contextual/queryable.rb +1 -4
- data/lib/mongoid/contextual.rb +18 -7
- data/lib/mongoid/copyable.rb +7 -9
- data/lib/mongoid/criteria/findable.rb +5 -7
- data/lib/mongoid/criteria/includable.rb +67 -14
- data/lib/mongoid/criteria/inspectable.rb +2 -5
- data/lib/mongoid/criteria/marshalable.rb +4 -8
- data/lib/mongoid/criteria/modifiable.rb +3 -11
- data/lib/mongoid/criteria/options.rb +0 -3
- data/lib/mongoid/criteria/permission.rb +34 -37
- data/lib/mongoid/criteria/queryable/aggregable.rb +9 -10
- data/lib/mongoid/criteria/queryable/expandable.rb +4 -9
- data/lib/mongoid/criteria/queryable/extensions/array.rb +7 -10
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -5
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -4
- data/lib/mongoid/criteria/queryable/extensions/date.rb +2 -6
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +3 -7
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -4
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +20 -11
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +15 -11
- data/lib/mongoid/criteria/queryable/extensions/object.rb +7 -8
- data/lib/mongoid/criteria/queryable/extensions/range.rb +6 -9
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +10 -12
- data/lib/mongoid/criteria/queryable/extensions/set.rb +4 -6
- data/lib/mongoid/criteria/queryable/extensions/string.rb +5 -9
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +3 -7
- data/lib/mongoid/criteria/queryable/extensions/time.rb +2 -6
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +2 -12
- data/lib/mongoid/criteria/queryable/extensions.rb +18 -21
- data/lib/mongoid/criteria/queryable/key.rb +12 -18
- data/lib/mongoid/criteria/queryable/macroable.rb +0 -3
- data/lib/mongoid/criteria/queryable/mergeable.rb +35 -39
- data/lib/mongoid/criteria/queryable/optional.rb +17 -18
- data/lib/mongoid/criteria/queryable/options.rb +20 -9
- data/lib/mongoid/criteria/queryable/pipeline.rb +6 -9
- data/lib/mongoid/criteria/queryable/selectable.rb +253 -199
- data/lib/mongoid/criteria/queryable/selector.rb +20 -29
- data/lib/mongoid/criteria/queryable/smash.rb +1 -6
- data/lib/mongoid/criteria/queryable/storable.rb +20 -39
- data/lib/mongoid/criteria/queryable.rb +25 -15
- data/lib/mongoid/criteria/scopable.rb +5 -11
- data/lib/mongoid/criteria/translator.rb +5 -8
- data/lib/mongoid/criteria.rb +109 -54
- data/lib/mongoid/deprecable.rb +45 -5
- data/lib/mongoid/deprecation.rb +2 -6
- data/lib/mongoid/document.rb +1 -1
- data/lib/mongoid/encryptable.rb +47 -2
- data/lib/mongoid/equality.rb +4 -5
- data/lib/mongoid/errors/ambiguous_relationship.rb +2 -5
- data/lib/mongoid/errors/attribute_not_loaded.rb +1 -4
- data/lib/mongoid/errors/callback.rb +1 -4
- data/lib/mongoid/errors/config_redactor.rb +43 -0
- data/lib/mongoid/errors/create_collection_failure.rb +8 -11
- data/lib/mongoid/errors/criteria_argument_required.rb +2 -5
- data/lib/mongoid/errors/delete_restriction.rb +1 -4
- data/lib/mongoid/errors/document_not_destroyed.rb +1 -4
- data/lib/mongoid/errors/document_not_found.rb +16 -21
- data/lib/mongoid/errors/drop_collection_failure.rb +7 -10
- data/lib/mongoid/errors/empty_config_file.rb +1 -4
- data/lib/mongoid/errors/immutable_attribute.rb +1 -4
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -4
- data/lib/mongoid/errors/in_memory_regexp_timeout.rb +26 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +2 -5
- data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +2 -5
- data/lib/mongoid/errors/invalid_collection.rb +1 -3
- data/lib/mongoid/errors/invalid_config_file.rb +1 -4
- data/lib/mongoid/errors/invalid_config_option.rb +2 -5
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +6 -10
- data/lib/mongoid/errors/invalid_discriminator_key_target.rb +2 -4
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +1 -4
- data/lib/mongoid/errors/invalid_elem_match_operator.rb +5 -9
- data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +1 -4
- data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +1 -4
- data/lib/mongoid/errors/invalid_expression_operator.rb +3 -7
- data/lib/mongoid/errors/invalid_field.rb +2 -5
- data/lib/mongoid/errors/invalid_field_operator.rb +5 -9
- data/lib/mongoid/errors/invalid_field_option.rb +2 -5
- data/lib/mongoid/errors/invalid_field_type.rb +1 -4
- data/lib/mongoid/errors/invalid_find.rb +1 -4
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +1 -4
- data/lib/mongoid/errors/invalid_includes.rb +3 -6
- data/lib/mongoid/errors/invalid_index.rb +1 -4
- data/lib/mongoid/errors/invalid_options.rb +1 -4
- data/lib/mongoid/errors/invalid_path.rb +1 -4
- data/lib/mongoid/errors/invalid_persistence_option.rb +4 -7
- data/lib/mongoid/errors/invalid_query.rb +6 -11
- data/lib/mongoid/errors/invalid_relation.rb +10 -13
- data/lib/mongoid/errors/invalid_relation_option.rb +4 -7
- data/lib/mongoid/errors/invalid_scope.rb +1 -4
- data/lib/mongoid/errors/invalid_session_nesting.rb +0 -3
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +2 -4
- data/lib/mongoid/errors/invalid_storage_options.rb +1 -4
- data/lib/mongoid/errors/invalid_time.rb +1 -4
- data/lib/mongoid/errors/invalid_transaction_nesting.rb +0 -3
- data/lib/mongoid/errors/inverse_not_found.rb +1 -4
- data/lib/mongoid/errors/mixed_client_configuration.rb +2 -5
- data/lib/mongoid/errors/mixed_relations.rb +1 -3
- data/lib/mongoid/errors/mongoid_error.rb +7 -11
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -4
- data/lib/mongoid/errors/no_client_config.rb +1 -4
- data/lib/mongoid/errors/no_client_database.rb +2 -5
- data/lib/mongoid/errors/no_client_hosts.rb +2 -5
- data/lib/mongoid/errors/no_clients_config.rb +1 -4
- data/lib/mongoid/errors/no_default_client.rb +1 -4
- data/lib/mongoid/errors/no_encryption_schema.rb +28 -0
- data/lib/mongoid/errors/no_environment.rb +1 -4
- data/lib/mongoid/errors/no_map_reduce_output.rb +1 -4
- data/lib/mongoid/errors/no_metadata.rb +1 -4
- data/lib/mongoid/errors/no_parent.rb +1 -4
- data/lib/mongoid/errors/readonly_association.rb +29 -0
- data/lib/mongoid/errors/readonly_attribute.rb +1 -4
- data/lib/mongoid/errors/readonly_document.rb +1 -4
- data/lib/mongoid/errors/rollback.rb +0 -2
- data/lib/mongoid/errors/scope_overwrite.rb +2 -4
- data/lib/mongoid/errors/sessions_not_supported.rb +0 -3
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -3
- data/lib/mongoid/errors/transaction_error.rb +0 -3
- data/lib/mongoid/errors/transactions_not_supported.rb +0 -3
- data/lib/mongoid/errors/unknown_attribute.rb +1 -4
- data/lib/mongoid/errors/unknown_model.rb +1 -4
- data/lib/mongoid/errors/unregistered_class.rb +1 -1
- data/lib/mongoid/errors/unsaved_document.rb +1 -3
- data/lib/mongoid/errors/unsupported_isolation_level.rb +22 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +1 -4
- data/lib/mongoid/errors/validations.rb +3 -5
- data/lib/mongoid/errors.rb +76 -72
- data/lib/mongoid/evolvable.rb +0 -3
- data/lib/mongoid/extensions/array.rb +5 -7
- data/lib/mongoid/extensions/big_decimal.rb +6 -7
- data/lib/mongoid/extensions/binary.rb +3 -6
- data/lib/mongoid/extensions/boolean.rb +4 -7
- data/lib/mongoid/extensions/bson_document.rb +28 -0
- data/lib/mongoid/extensions/date.rb +10 -14
- data/lib/mongoid/extensions/date_time.rb +2 -6
- data/lib/mongoid/extensions/decimal128.rb +1 -5
- data/lib/mongoid/extensions/false_class.rb +3 -5
- data/lib/mongoid/extensions/float.rb +5 -10
- data/lib/mongoid/extensions/hash.rb +5 -10
- data/lib/mongoid/extensions/integer.rb +5 -10
- data/lib/mongoid/extensions/module.rb +1 -4
- data/lib/mongoid/extensions/nil_class.rb +0 -1
- data/lib/mongoid/extensions/object.rb +9 -14
- data/lib/mongoid/extensions/object_id.rb +2 -6
- data/lib/mongoid/extensions/range.rb +14 -15
- data/lib/mongoid/extensions/raw_value.rb +0 -3
- data/lib/mongoid/extensions/regexp.rb +3 -6
- data/lib/mongoid/extensions/set.rb +3 -4
- data/lib/mongoid/extensions/string.rb +8 -12
- data/lib/mongoid/extensions/symbol.rb +3 -7
- data/lib/mongoid/extensions/time.rb +24 -26
- data/lib/mongoid/extensions/time_with_zone.rb +4 -7
- data/lib/mongoid/extensions/true_class.rb +3 -5
- data/lib/mongoid/extensions/vector.rb +64 -0
- data/lib/mongoid/extensions.rb +27 -26
- data/lib/mongoid/factory.rb +5 -9
- data/lib/mongoid/field_readable.rb +69 -0
- data/lib/mongoid/fields/encrypted.rb +0 -1
- data/lib/mongoid/fields/foreign_key.rb +9 -10
- data/lib/mongoid/fields/localized.rb +12 -12
- data/lib/mongoid/fields/standard.rb +5 -7
- data/lib/mongoid/fields/validators/macro.rb +23 -34
- data/lib/mongoid/fields/validators.rb +1 -2
- data/lib/mongoid/fields.rb +151 -58
- data/lib/mongoid/findable.rb +82 -53
- data/lib/mongoid/indexable/specification.rb +20 -6
- data/lib/mongoid/indexable/validators/options.rb +33 -40
- data/lib/mongoid/indexable.rb +53 -40
- data/lib/mongoid/inspectable.rb +4 -7
- data/lib/mongoid/interceptable.rb +41 -40
- data/lib/mongoid/loadable.rb +17 -18
- data/lib/mongoid/loggable.rb +4 -8
- data/lib/mongoid/matchable.rb +6 -3
- data/lib/mongoid/matcher/all.rb +2 -5
- data/lib/mongoid/matcher/and.rb +0 -3
- data/lib/mongoid/matcher/bits.rb +13 -8
- data/lib/mongoid/matcher/bits_all_clear.rb +1 -3
- data/lib/mongoid/matcher/bits_all_set.rb +1 -3
- data/lib/mongoid/matcher/bits_any_clear.rb +1 -3
- data/lib/mongoid/matcher/bits_any_set.rb +1 -3
- data/lib/mongoid/matcher/elem_match.rb +13 -15
- data/lib/mongoid/matcher/elem_match_expression.rb +0 -3
- data/lib/mongoid/matcher/eq.rb +0 -3
- data/lib/mongoid/matcher/eq_impl.rb +12 -17
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +4 -9
- data/lib/mongoid/matcher/exists.rb +1 -4
- data/lib/mongoid/matcher/expression.rb +5 -10
- data/lib/mongoid/matcher/expression_operator.rb +1 -3
- data/lib/mongoid/matcher/field_expression.rb +10 -13
- data/lib/mongoid/matcher/field_operator.rb +4 -6
- data/lib/mongoid/matcher/gt.rb +0 -3
- data/lib/mongoid/matcher/gte.rb +0 -3
- data/lib/mongoid/matcher/in.rb +9 -12
- data/lib/mongoid/matcher/lt.rb +0 -3
- data/lib/mongoid/matcher/lte.rb +0 -3
- data/lib/mongoid/matcher/mod.rb +4 -8
- data/lib/mongoid/matcher/ne.rb +0 -3
- data/lib/mongoid/matcher/nin.rb +0 -3
- data/lib/mongoid/matcher/nor.rb +1 -6
- data/lib/mongoid/matcher/not.rb +0 -3
- data/lib/mongoid/matcher/or.rb +0 -3
- data/lib/mongoid/matcher/regex.rb +9 -13
- data/lib/mongoid/matcher/regexp_budget.rb +372 -0
- data/lib/mongoid/matcher/size.rb +2 -5
- data/lib/mongoid/matcher/type.rb +32 -37
- data/lib/mongoid/matcher.rb +8 -15
- data/lib/mongoid/model_resolver.rb +1 -0
- data/lib/mongoid/persistable/creatable.rb +23 -7
- data/lib/mongoid/persistable/deletable.rb +6 -7
- data/lib/mongoid/persistable/destroyable.rb +2 -6
- data/lib/mongoid/persistable/incrementable.rb +1 -3
- data/lib/mongoid/persistable/logical.rb +3 -5
- data/lib/mongoid/persistable/maxable.rb +2 -4
- data/lib/mongoid/persistable/minable.rb +2 -4
- data/lib/mongoid/persistable/multipliable.rb +1 -3
- data/lib/mongoid/persistable/poppable.rb +2 -4
- data/lib/mongoid/persistable/pullable.rb +3 -5
- data/lib/mongoid/persistable/pushable.rb +5 -7
- data/lib/mongoid/persistable/renamable.rb +1 -3
- data/lib/mongoid/persistable/savable.rb +0 -3
- data/lib/mongoid/persistable/settable.rb +4 -13
- data/lib/mongoid/persistable/unsettable.rb +1 -3
- data/lib/mongoid/persistable/updatable.rb +23 -33
- data/lib/mongoid/persistable/upsertable.rb +8 -10
- data/lib/mongoid/persistable.rb +28 -27
- data/lib/mongoid/persistence_context.rb +69 -41
- data/lib/mongoid/pluckable.rb +0 -2
- data/lib/mongoid/positional.rb +5 -11
- data/lib/mongoid/railtie.rb +16 -22
- data/lib/mongoid/railties/console_sandbox.rb +6 -8
- data/lib/mongoid/railties/controller_runtime.rb +7 -11
- data/lib/mongoid/railties/database.rake +42 -44
- data/lib/mongoid/scopable.rb +23 -31
- data/lib/mongoid/search_indexable.rb +378 -7
- data/lib/mongoid/selectable.rb +1 -3
- data/lib/mongoid/serializable.rb +18 -12
- data/lib/mongoid/shardable.rb +8 -17
- data/lib/mongoid/stateful.rb +5 -10
- data/lib/mongoid/stringified_symbol.rb +5 -9
- data/lib/mongoid/tasks/database.rake +31 -32
- data/lib/mongoid/tasks/database.rb +51 -39
- data/lib/mongoid/tasks/encryption.rb +10 -15
- data/lib/mongoid/threaded/lifecycle.rb +6 -9
- data/lib/mongoid/threaded.rb +168 -32
- data/lib/mongoid/timestamps/created/short.rb +2 -3
- data/lib/mongoid/timestamps/created.rb +1 -2
- data/lib/mongoid/timestamps/short.rb +0 -1
- data/lib/mongoid/timestamps/timeless.rb +92 -23
- data/lib/mongoid/timestamps/updated/short.rb +2 -3
- data/lib/mongoid/timestamps/updated.rb +2 -5
- data/lib/mongoid/timestamps.rb +4 -6
- data/lib/mongoid/touchable.rb +19 -11
- data/lib/mongoid/traversable.rb +5 -4
- data/lib/mongoid/validatable/associated.rb +19 -7
- data/lib/mongoid/validatable/format.rb +0 -2
- data/lib/mongoid/validatable/length.rb +0 -2
- data/lib/mongoid/validatable/localizable.rb +0 -3
- data/lib/mongoid/validatable/macros.rb +0 -2
- data/lib/mongoid/validatable/numericality.rb +24 -3
- data/lib/mongoid/validatable/presence.rb +8 -10
- data/lib/mongoid/validatable/queryable.rb +0 -3
- data/lib/mongoid/validatable/uniqueness.rb +12 -14
- data/lib/mongoid/validatable.rb +15 -20
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +10 -11
- data/lib/mongoid.rb +30 -34
- data/lib/rails/generators/mongoid/config/config_generator.rb +2 -4
- data/lib/rails/generators/mongoid/config/templates/mongoid.rb +4 -5
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +2 -2
- data/lib/rails/generators/mongoid/model/model_generator.rb +5 -8
- data/lib/rails/generators/mongoid_generator.rb +6 -10
- data/lib/rails/mongoid.rb +1 -3
- data/spec/integration/active_job_spec.rb +1 -2
- data/spec/integration/app_spec.rb +149 -179
- data/spec/integration/associations/belongs_to_spec.rb +43 -28
- data/spec/integration/associations/embedded_dirty_spec.rb +0 -1
- data/spec/integration/associations/embedded_spec.rb +41 -43
- data/spec/integration/associations/embeds_many_spec.rb +46 -29
- data/spec/integration/associations/embeds_one_spec.rb +2 -1
- data/spec/integration/associations/foreign_key_spec.rb +10 -11
- data/spec/integration/associations/foreign_key_spec_models.rb +8 -9
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +33 -15
- data/spec/integration/associations/has_many_spec.rb +17 -18
- data/spec/integration/associations/has_one_spec.rb +42 -45
- data/spec/integration/associations/nested_attributes_assignment_spec.rb +36 -39
- data/spec/integration/associations/reverse_population_spec.rb +4 -5
- data/spec/integration/associations/reverse_population_spec_models.rb +0 -1
- data/spec/integration/associations/scope_option_spec.rb +18 -20
- data/spec/integration/atomic/modifiers_spec.rb +72 -52
- data/spec/integration/bson_regexp_raw_spec.rb +2 -3
- data/spec/integration/caching_spec.rb +68 -0
- data/spec/integration/callbacks_models.rb +11 -9
- data/spec/integration/callbacks_spec.rb +78 -80
- data/spec/integration/contextual/empty_spec.rb +19 -20
- data/spec/integration/criteria/alias_query_spec.rb +12 -19
- data/spec/integration/criteria/date_field_spec.rb +1 -2
- data/spec/integration/criteria/default_scope_spec.rb +23 -18
- data/spec/integration/criteria/logical_spec.rb +18 -19
- data/spec/integration/criteria/range_spec.rb +77 -86
- data/spec/integration/criteria/raw_value_spec.rb +122 -109
- data/spec/integration/criteria/time_with_zone_spec.rb +33 -24
- data/spec/integration/discriminator_key_spec.rb +85 -85
- data/spec/integration/discriminator_value_spec.rb +70 -73
- data/spec/integration/document_spec.rb +9 -10
- data/spec/integration/dots_and_dollars_spec.rb +115 -120
- data/spec/integration/encryption_spec.rb +157 -9
- data/spec/integration/i18n_fallbacks_spec.rb +7 -8
- data/spec/integration/isolation_state_spec.rb +241 -0
- data/spec/integration/matcher_examples_spec.rb +145 -168
- data/spec/integration/matcher_operator_data/in.yml +6 -6
- data/spec/integration/matcher_operator_data/regex.yml +21 -0
- data/spec/integration/matcher_operator_spec.rb +16 -26
- data/spec/integration/matcher_regexp_timeout_spec.rb +215 -0
- data/spec/integration/matcher_spec.rb +31 -32
- data/spec/integration/persistence/collection_options_spec.rb +0 -2
- data/spec/integration/persistence/range_field_spec.rb +24 -2
- data/spec/integration/query_operator_guard_spec.rb +89 -0
- data/spec/integration/server_query_spec.rb +43 -37
- data/spec/integration/shardable_spec.rb +10 -11
- data/spec/integration/stringified_symbol_field_spec.rb +28 -43
- data/spec/lite_spec_helper.rb +11 -12
- data/spec/mongoid/association/accessors_spec.rb +197 -285
- data/spec/mongoid/association/auto_save_spec.rb +62 -93
- data/spec/mongoid/association/builders_spec.rb +121 -74
- data/spec/mongoid/association/constrainable_spec.rb +9 -22
- data/spec/mongoid/association/counter_cache_spec.rb +71 -104
- data/spec/mongoid/association/depending_spec.rb +166 -208
- data/spec/mongoid/association/eager_loadable_spec.rb +47 -0
- data/spec/mongoid/association/eager_spec.rb +416 -80
- data/spec/mongoid/association/embedded/cyclic_spec.rb +36 -48
- data/spec/mongoid/association/embedded/dirty_spec.rb +15 -20
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +36 -54
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +8 -15
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +135 -175
- data/spec/mongoid/association/embedded/embedded_in_spec.rb +25 -127
- data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +9 -14
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +38 -51
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +1184 -1340
- data/spec/mongoid/association/embedded/embeds_many_models.rb +17 -17
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +11 -11
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +25 -138
- data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +15 -23
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +18 -26
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +204 -273
- data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +0 -1
- data/spec/mongoid/association/embedded/embeds_one_models.rb +0 -1
- data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +5 -6
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -143
- data/spec/mongoid/association/fallback_spec.rb +425 -0
- data/spec/mongoid/association/macros_spec.rb +239 -300
- data/spec/mongoid/association/nested/many_spec.rb +51 -73
- data/spec/mongoid/association/nested/one_spec.rb +56 -80
- data/spec/mongoid/association/options_spec.rb +187 -310
- data/spec/mongoid/association/polymorphic_spec.rb +35 -53
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +55 -76
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +36 -41
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +98 -101
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +258 -345
- data/spec/mongoid/association/referenced/belongs_to_models.rb +4 -3
- data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +3 -4
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +91 -294
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +42 -56
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +41 -32
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +36 -42
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +8 -9
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +819 -975
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +9 -9
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +5 -6
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +109 -177
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +29 -43
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +53 -53
- data/spec/mongoid/association/referenced/has_many/eager_spec.rb +137 -67
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +431 -675
- data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -2
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +318 -11
- data/spec/mongoid/association/referenced/has_many_models.rb +1 -2
- data/spec/mongoid/association/referenced/has_many_query_spec.rb +3 -4
- data/spec/mongoid/association/referenced/has_many_spec.rb +44 -188
- data/spec/mongoid/association/referenced/has_many_through/eager_spec.rb +58 -0
- data/spec/mongoid/association/referenced/has_many_through/proxy_spec.rb +62 -0
- data/spec/mongoid/association/referenced/has_many_through_spec.rb +399 -0
- data/spec/mongoid/association/referenced/has_one/binding_spec.rb +26 -38
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +28 -29
- data/spec/mongoid/association/referenced/has_one/eager_spec.rb +29 -42
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +270 -332
- data/spec/mongoid/association/referenced/has_one_models.rb +1 -2
- data/spec/mongoid/association/referenced/has_one_query_spec.rb +3 -4
- data/spec/mongoid/association/referenced/has_one_spec.rb +40 -188
- data/spec/mongoid/association/referenced/has_one_through/eager_spec.rb +58 -0
- data/spec/mongoid/association/referenced/has_one_through/proxy_spec.rb +49 -0
- data/spec/mongoid/association/referenced/has_one_through_spec.rb +211 -0
- data/spec/mongoid/association/reflections_spec.rb +14 -24
- data/spec/mongoid/association/syncable_spec.rb +102 -125
- data/spec/mongoid/association_spec.rb +47 -70
- data/spec/mongoid/atomic/modifiers_spec.rb +184 -197
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +39 -52
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +35 -49
- data/spec/mongoid/atomic/paths/root_spec.rb +9 -15
- data/spec/mongoid/atomic/paths_spec.rb +81 -117
- data/spec/mongoid/atomic_spec.rb +156 -171
- data/spec/mongoid/attributes/dynamic_spec.rb +5 -6
- data/spec/mongoid/attributes/nested_spec.rb +1461 -1693
- data/spec/mongoid/attributes/nested_spec_models.rb +8 -9
- data/spec/mongoid/attributes/projector_spec.rb +2 -6
- data/spec/mongoid/attributes/readonly_spec.rb +73 -97
- data/spec/mongoid/attributes_spec.rb +669 -826
- data/spec/mongoid/cacheable_spec.rb +74 -44
- data/spec/mongoid/changeable_spec.rb +591 -733
- data/spec/mongoid/clients/factory_spec.rb +122 -154
- data/spec/mongoid/clients/options_spec.rb +40 -59
- data/spec/mongoid/clients/sessions_spec.rb +25 -44
- data/spec/mongoid/clients/transactions_spec.rb +33 -50
- data/spec/mongoid/clients/transactions_spec_models.rb +3 -4
- data/spec/mongoid/clients_spec.rb +265 -355
- data/spec/mongoid/collection_configurable_spec.rb +9 -12
- data/spec/mongoid/composable_spec.rb +2 -9
- data/spec/mongoid/config/defaults_spec.rb +56 -30
- data/spec/mongoid/config/encryption_spec.rb +282 -57
- data/spec/mongoid/config/environment_spec.rb +30 -40
- data/spec/mongoid/config/introspection_spec.rb +42 -37
- data/spec/mongoid/config/options_spec.rb +14 -21
- data/spec/mongoid/config_spec.rb +145 -195
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +189 -135
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +4 -7
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +149 -187
- data/spec/mongoid/contextual/aggregable/none_spec.rb +14 -16
- data/spec/mongoid/contextual/atomic_spec.rb +223 -271
- data/spec/mongoid/contextual/map_reduce_spec.rb +110 -138
- data/spec/mongoid/contextual/memory_spec.rb +883 -854
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +12 -13
- data/spec/mongoid/contextual/mongo_spec.rb +1008 -1213
- data/spec/mongoid/contextual/none_spec.rb +54 -59
- data/spec/mongoid/contextual/short_circuit_spec.rb +139 -0
- data/spec/mongoid/copyable_spec.rb +254 -300
- data/spec/mongoid/copyable_spec_models.rb +0 -1
- data/spec/mongoid/criteria/findable_spec.rb +322 -387
- data/spec/mongoid/criteria/includable_spec.rb +1356 -432
- data/spec/mongoid/criteria/includable_spec_models.rb +16 -7
- data/spec/mongoid/criteria/inspectable_spec.rb +11 -14
- data/spec/mongoid/criteria/marshalable_spec.rb +11 -14
- data/spec/mongoid/criteria/modifiable_spec.rb +366 -512
- data/spec/mongoid/criteria/options_spec.rb +2 -7
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +112 -141
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +8 -11
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +127 -184
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +123 -60
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +84 -117
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +44 -65
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +86 -108
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +94 -33
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +103 -138
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +95 -34
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +25 -38
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +26 -28
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +32 -54
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +136 -130
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +16 -24
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +15 -24
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +12 -19
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +46 -63
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +28 -42
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +73 -96
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +71 -92
- data/spec/mongoid/criteria/queryable/key_spec.rb +32 -36
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +44 -49
- data/spec/mongoid/criteria/queryable/optional_spec.rb +373 -486
- data/spec/mongoid/criteria/queryable/options_spec.rb +172 -123
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +65 -87
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +41 -53
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +589 -679
- data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +7 -11
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +807 -998
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +354 -190
- data/spec/mongoid/criteria/queryable/selector_spec.rb +294 -390
- data/spec/mongoid/criteria/queryable/smash_spec.rb +6 -11
- data/spec/mongoid/criteria/queryable/storable_spec.rb +54 -81
- data/spec/mongoid/criteria/queryable_mql_spec.rb +92 -0
- data/spec/mongoid/criteria/scopable_spec.rb +102 -138
- data/spec/mongoid/criteria/translator_spec.rb +59 -60
- data/spec/mongoid/criteria_projection_spec.rb +81 -99
- data/spec/mongoid/criteria_spec.rb +937 -949
- data/spec/mongoid/document_fields_spec.rb +28 -30
- data/spec/mongoid/document_persistence_context_spec.rb +13 -15
- data/spec/mongoid/document_query_spec.rb +9 -12
- data/spec/mongoid/document_spec.rb +317 -409
- data/spec/mongoid/encryptable_spec.rb +61 -0
- data/spec/mongoid/equality_spec.rb +69 -102
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +8 -11
- data/spec/mongoid/errors/attribute_not_loaded_spec.rb +7 -10
- data/spec/mongoid/errors/callback_spec.rb +8 -11
- data/spec/mongoid/errors/config_redactor_spec.rb +112 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +5 -8
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +7 -10
- data/spec/mongoid/errors/document_not_found_spec.rb +51 -61
- data/spec/mongoid/errors/invalid_collection_spec.rb +9 -13
- data/spec/mongoid/errors/invalid_config_file_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_config_option_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_field_option_spec.rb +7 -10
- data/spec/mongoid/errors/invalid_field_spec.rb +10 -11
- data/spec/mongoid/errors/invalid_field_type_spec.rb +9 -12
- data/spec/mongoid/errors/invalid_find_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_includes_spec.rb +9 -13
- data/spec/mongoid/errors/invalid_index_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_options_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_path_spec.rb +7 -10
- data/spec/mongoid/errors/invalid_relation_spec.rb +15 -16
- data/spec/mongoid/errors/invalid_scope_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -6
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +8 -11
- data/spec/mongoid/errors/invalid_time_spec.rb +8 -11
- data/spec/mongoid/errors/inverse_not_found_spec.rb +9 -12
- data/spec/mongoid/errors/mixed_client_configuration_spec.rb +40 -12
- data/spec/mongoid/errors/mixed_relations_spec.rb +8 -11
- data/spec/mongoid/errors/mongoid_error_spec.rb +21 -24
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +6 -9
- data/spec/mongoid/errors/no_client_config_spec.rb +7 -10
- data/spec/mongoid/errors/no_client_database_spec.rb +38 -12
- data/spec/mongoid/errors/no_client_hosts_spec.rb +35 -12
- data/spec/mongoid/errors/no_clients_config_spec.rb +7 -10
- data/spec/mongoid/errors/no_environment_spec.rb +8 -11
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +8 -11
- data/spec/mongoid/errors/no_metadata_spec.rb +7 -10
- data/spec/mongoid/errors/no_parent_spec.rb +7 -10
- data/spec/mongoid/errors/readonly_association_spec.rb +34 -0
- data/spec/mongoid/errors/readonly_attribute_spec.rb +7 -10
- data/spec/mongoid/errors/readonly_document_spec.rb +6 -9
- data/spec/mongoid/errors/scope_overwrite_spec.rb +9 -12
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +9 -12
- data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -8
- data/spec/mongoid/errors/unsaved_document_spec.rb +8 -11
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +9 -12
- data/spec/mongoid/errors/validations_spec.rb +11 -14
- data/spec/mongoid/extensions/array_spec.rb +70 -92
- data/spec/mongoid/extensions/big_decimal_spec.rb +233 -313
- data/spec/mongoid/extensions/binary_spec.rb +21 -32
- data/spec/mongoid/extensions/boolean_spec.rb +52 -75
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +43 -54
- data/spec/mongoid/extensions/date_spec.rb +26 -38
- data/spec/mongoid/extensions/date_time_spec.rb +22 -32
- data/spec/mongoid/extensions/decimal128_spec.rb +12 -18
- data/spec/mongoid/extensions/false_class_spec.rb +10 -17
- data/spec/mongoid/extensions/float_spec.rb +40 -61
- data/spec/mongoid/extensions/hash_spec.rb +46 -64
- data/spec/mongoid/extensions/integer_spec.rb +40 -61
- data/spec/mongoid/extensions/module_spec.rb +13 -18
- data/spec/mongoid/extensions/nil_class_spec.rb +2 -5
- data/spec/mongoid/extensions/object_id_spec.rb +159 -247
- data/spec/mongoid/extensions/object_spec.rb +31 -47
- data/spec/mongoid/extensions/range_spec.rb +112 -115
- data/spec/mongoid/extensions/raw_value_spec.rb +10 -12
- data/spec/mongoid/extensions/regexp_spec.rb +23 -36
- data/spec/mongoid/extensions/set_spec.rb +38 -49
- data/spec/mongoid/extensions/string_spec.rb +118 -167
- data/spec/mongoid/extensions/stringified_symbol_spec.rb +29 -43
- data/spec/mongoid/extensions/symbol_spec.rb +12 -20
- data/spec/mongoid/extensions/time_spec.rb +160 -202
- data/spec/mongoid/extensions/time_with_zone_spec.rb +79 -105
- data/spec/mongoid/extensions/true_class_spec.rb +10 -17
- data/spec/mongoid/extensions/vector_spec.rb +175 -0
- data/spec/mongoid/factory_spec.rb +125 -148
- data/spec/mongoid/fields/foreign_key_spec.rb +124 -169
- data/spec/mongoid/fields/localized_spec.rb +140 -185
- data/spec/mongoid/fields/standard_spec.rb +43 -59
- data/spec/mongoid/fields_spec.rb +751 -620
- data/spec/mongoid/findable_spec.rb +260 -228
- data/spec/mongoid/indexable/specification_spec.rb +42 -58
- data/spec/mongoid/indexable_spec.rb +260 -264
- data/spec/mongoid/inspectable_spec.rb +45 -55
- data/spec/mongoid/interceptable_spec.rb +784 -922
- data/spec/mongoid/interceptable_spec_models.rb +35 -35
- data/spec/mongoid/loading_spec.rb +47 -43
- data/spec/mongoid/loggable_spec.rb +3 -6
- data/spec/mongoid/matcher/extract_attribute_spec.rb +2 -6
- data/spec/mongoid/matcher/regexp_budget_spec.rb +570 -0
- data/spec/mongoid/mongoizable_spec.rb +81 -90
- data/spec/mongoid/monkey_patches_spec.rb +4 -0
- data/spec/mongoid/persistable/creatable_spec.rb +181 -220
- data/spec/mongoid/persistable/deletable_spec.rb +139 -179
- data/spec/mongoid/persistable/destroyable_spec.rb +135 -164
- data/spec/mongoid/persistable/incrementable_spec.rb +65 -84
- data/spec/mongoid/persistable/logical_spec.rb +48 -61
- data/spec/mongoid/persistable/maxable_spec.rb +45 -44
- data/spec/mongoid/persistable/minable_spec.rb +45 -44
- data/spec/mongoid/persistable/multipliable_spec.rb +54 -69
- data/spec/mongoid/persistable/poppable_spec.rb +47 -60
- data/spec/mongoid/persistable/pullable_spec.rb +79 -103
- data/spec/mongoid/persistable/pushable_spec.rb +106 -131
- data/spec/mongoid/persistable/renamable_spec.rb +52 -65
- data/spec/mongoid/persistable/savable_spec.rb +152 -189
- data/spec/mongoid/persistable/settable_spec.rb +121 -145
- data/spec/mongoid/persistable/unsettable_spec.rb +56 -73
- data/spec/mongoid/persistable/updatable_spec.rb +185 -232
- data/spec/mongoid/persistable/upsertable_spec.rb +66 -77
- data/spec/mongoid/persistable_spec.rb +132 -139
- data/spec/mongoid/persistence_context_spec.rb +31 -89
- data/spec/mongoid/positional_spec.rb +67 -79
- data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +0 -3
- data/spec/mongoid/railties/console_sandbox_spec.rb +0 -1
- data/spec/mongoid/relations/proxy_spec.rb +0 -1
- data/spec/mongoid/reloadable_spec.rb +250 -145
- data/spec/mongoid/scopable_spec.rb +319 -398
- data/spec/mongoid/search_indexable_spec.rb +735 -44
- data/spec/mongoid/selectable_spec.rb +36 -51
- data/spec/mongoid/serializable_spec.rb +269 -312
- data/spec/mongoid/shardable_models.rb +5 -5
- data/spec/mongoid/shardable_spec.rb +44 -46
- data/spec/mongoid/stateful_spec.rb +55 -75
- data/spec/mongoid/tasks/database_rake_spec.rb +138 -141
- data/spec/mongoid/tasks/database_spec.rb +98 -80
- data/spec/mongoid/tasks/encryption_spec.rb +22 -20
- data/spec/mongoid/threaded_spec.rb +57 -83
- data/spec/mongoid/timestamps/created/short_spec.rb +12 -16
- data/spec/mongoid/timestamps/created_spec.rb +16 -20
- data/spec/mongoid/timestamps/timeless_spec.rb +228 -48
- data/spec/mongoid/timestamps/updated/short_spec.rb +21 -28
- data/spec/mongoid/timestamps/updated_spec.rb +18 -25
- data/spec/mongoid/timestamps_spec.rb +171 -188
- data/spec/mongoid/timestamps_spec_models.rb +12 -13
- data/spec/mongoid/touchable_spec.rb +355 -294
- data/spec/mongoid/touchable_spec_models.rb +45 -37
- data/spec/mongoid/traversable_spec.rb +435 -471
- data/spec/mongoid/validatable/associated_spec.rb +60 -59
- data/spec/mongoid/validatable/format_spec.rb +24 -34
- data/spec/mongoid/validatable/length_spec.rb +62 -86
- data/spec/mongoid/validatable/numericality_spec.rb +114 -23
- data/spec/mongoid/validatable/presence_spec.rb +149 -203
- data/spec/mongoid/validatable/uniqueness_spec.rb +632 -830
- data/spec/mongoid/validatable_spec.rb +71 -103
- data/spec/mongoid/warnings_spec.rb +5 -9
- data/spec/mongoid_spec.rb +25 -41
- data/spec/rails/controller_extension/controller_runtime_spec.rb +45 -49
- data/spec/rails/mongoid_spec.rb +15 -15
- data/spec/shared/lib/mrss/cluster_config.rb +5 -40
- data/spec/shared/lib/mrss/constraints.rb +7 -46
- data/spec/shared/lib/mrss/docker_runner.rb +10 -21
- data/spec/shared/lib/mrss/eg_config_utils.rb +0 -31
- data/spec/shared/lib/mrss/release/candidate.rb +18 -12
- data/spec/shared/lib/mrss/server_version_registry.rb +1 -5
- data/spec/shared/share/Dockerfile.erb +6 -8
- data/spec/shared/shlib/server.sh +0 -50
- data/spec/shared/shlib/set_env.sh +4 -10
- data/spec/spec_helper.rb +59 -32
- data/spec/support/authorization.rb +0 -1
- data/spec/support/client_registry.rb +1 -2
- data/spec/support/constraints.rb +8 -25
- data/spec/support/crypt/models.rb +164 -8
- data/spec/support/crypt.rb +6 -9
- data/spec/support/expectations.rb +21 -7
- data/spec/support/feature_sandbox.rb +1 -4
- data/spec/support/helpers.rb +0 -1
- data/spec/support/immutable_ids.rb +20 -21
- data/spec/support/macros.rb +1 -3
- data/spec/support/models/account.rb +4 -5
- data/spec/support/models/acolyte.rb +5 -5
- data/spec/support/models/actor.rb +3 -3
- data/spec/support/models/actress.rb +0 -1
- data/spec/support/models/address.rb +11 -11
- 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 -2
- data/spec/support/models/alert.rb +1 -1
- data/spec/support/models/animal.rb +4 -5
- data/spec/support/models/answer.rb +1 -1
- data/spec/support/models/appointment.rb +2 -2
- data/spec/support/models/armrest.rb +0 -1
- data/spec/support/models/array_field.rb +0 -1
- data/spec/support/models/article.rb +0 -1
- data/spec/support/models/artist.rb +16 -12
- data/spec/support/models/artwork.rb +1 -1
- data/spec/support/models/audible_sound.rb +0 -1
- data/spec/support/models/audio.rb +2 -2
- data/spec/support/models/augmentation.rb +1 -2
- data/spec/support/models/author.rb +1 -1
- data/spec/support/models/baby.rb +1 -1
- data/spec/support/models/band.rb +0 -1
- data/spec/support/models/bar.rb +2 -2
- data/spec/support/models/basic.rb +0 -1
- data/spec/support/models/bed.rb +0 -1
- data/spec/support/models/big_palette.rb +0 -1
- data/spec/support/models/birthday.rb +3 -5
- data/spec/support/models/bolt.rb +0 -1
- data/spec/support/models/bomb.rb +1 -1
- data/spec/support/models/book.rb +1 -1
- data/spec/support/models/breed.rb +1 -1
- data/spec/support/models/browser.rb +1 -2
- data/spec/support/models/building.rb +0 -1
- data/spec/support/models/building_address.rb +1 -1
- data/spec/support/models/bus.rb +1 -1
- data/spec/support/models/business.rb +2 -2
- data/spec/support/models/callback_test.rb +1 -1
- data/spec/support/models/canvas.rb +5 -6
- data/spec/support/models/car.rb +0 -1
- data/spec/support/models/cat.rb +0 -2
- data/spec/support/models/catalog.rb +0 -1
- data/spec/support/models/category.rb +1 -1
- data/spec/support/models/child.rb +1 -1
- data/spec/support/models/child_doc.rb +5 -6
- data/spec/support/models/church.rb +1 -1
- data/spec/support/models/circle.rb +0 -1
- data/spec/support/models/circuit.rb +2 -2
- data/spec/support/models/circus.rb +0 -1
- data/spec/support/models/code.rb +2 -1
- data/spec/support/models/coding/pull_request.rb +0 -1
- data/spec/support/models/coding.rb +0 -1
- data/spec/support/models/comment.rb +0 -1
- data/spec/support/models/company.rb +0 -1
- data/spec/support/models/consumption_period.rb +0 -1
- data/spec/support/models/contextable_item.rb +1 -1
- data/spec/support/models/contractor.rb +1 -1
- data/spec/support/models/cookie.rb +0 -1
- data/spec/support/models/country_code.rb +2 -3
- data/spec/support/models/courier_job.rb +2 -2
- data/spec/support/models/cover.rb +0 -1
- data/spec/support/models/crate.rb +0 -1
- data/spec/support/models/customer.rb +0 -1
- data/spec/support/models/customer_address.rb +0 -1
- data/spec/support/models/deed.rb +1 -1
- data/spec/support/models/definition.rb +1 -1
- data/spec/support/models/delegating_patient.rb +0 -1
- data/spec/support/models/description.rb +0 -1
- data/spec/support/models/dictionary.rb +1 -1
- data/spec/support/models/division.rb +2 -2
- data/spec/support/models/doctor.rb +0 -1
- data/spec/support/models/dog.rb +2 -2
- data/spec/support/models/dokument.rb +1 -1
- data/spec/support/models/draft.rb +0 -1
- data/spec/support/models/dragon.rb +1 -1
- data/spec/support/models/driver.rb +2 -2
- 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 -2
- data/spec/support/models/entry.rb +1 -1
- data/spec/support/models/eraser.rb +0 -1
- data/spec/support/models/even.rb +1 -1
- data/spec/support/models/event.rb +3 -4
- 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 +0 -1
- data/spec/support/models/eye_bowl.rb +2 -3
- data/spec/support/models/face.rb +2 -3
- data/spec/support/models/fanatic.rb +1 -1
- data/spec/support/models/favorite.rb +1 -1
- data/spec/support/models/filesystem.rb +1 -1
- data/spec/support/models/fire_hydrant.rb +1 -1
- data/spec/support/models/firefox.rb +0 -1
- data/spec/support/models/fish.rb +0 -1
- data/spec/support/models/folder.rb +0 -2
- data/spec/support/models/folder_item.rb +1 -3
- data/spec/support/models/fruits.rb +9 -5
- data/spec/support/models/game.rb +3 -4
- data/spec/support/models/ghost.rb +0 -1
- data/spec/support/models/guitar.rb +0 -1
- data/spec/support/models/hole.rb +0 -1
- data/spec/support/models/home.rb +1 -1
- data/spec/support/models/house.rb +2 -2
- data/spec/support/models/html_writer.rb +0 -1
- data/spec/support/models/id_key.rb +3 -3
- data/spec/support/models/idnodef.rb +0 -1
- data/spec/support/models/image.rb +0 -1
- data/spec/support/models/implant.rb +1 -2
- data/spec/support/models/instrument.rb +2 -3
- data/spec/support/models/item.rb +2 -2
- data/spec/support/models/jar.rb +1 -2
- data/spec/support/models/kaleidoscope.rb +1 -1
- data/spec/support/models/kangaroo.rb +1 -1
- data/spec/support/models/label.rb +2 -2
- data/spec/support/models/language.rb +1 -1
- data/spec/support/models/lat_lng.rb +0 -1
- data/spec/support/models/league.rb +1 -1
- data/spec/support/models/learner.rb +0 -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 -2
- data/spec/support/models/manufacturer.rb +0 -1
- data/spec/support/models/meat.rb +1 -1
- data/spec/support/models/membership.rb +1 -1
- data/spec/support/models/message.rb +1 -2
- data/spec/support/models/minim.rb +0 -1
- data/spec/support/models/mixed_drink.rb +1 -1
- data/spec/support/models/modifier_models.rb +25 -0
- data/spec/support/models/mop.rb +0 -1
- data/spec/support/models/movie.rb +1 -1
- data/spec/support/models/my_hash.rb +1 -2
- data/spec/support/models/name.rb +4 -5
- data/spec/support/models/name_only.rb +0 -1
- data/spec/support/models/node.rb +1 -1
- data/spec/support/models/note.rb +3 -3
- data/spec/support/models/nut.rb +0 -1
- data/spec/support/models/odd.rb +1 -1
- data/spec/support/models/order.rb +1 -1
- data/spec/support/models/ordered_post.rb +1 -1
- 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 +0 -1
- data/spec/support/models/override.rb +3 -11
- data/spec/support/models/ownable.rb +1 -1
- data/spec/support/models/owner.rb +1 -1
- data/spec/support/models/pack.rb +0 -1
- data/spec/support/models/page.rb +3 -3
- data/spec/support/models/page_question.rb +1 -1
- data/spec/support/models/palette.rb +2 -2
- data/spec/support/models/parent.rb +2 -2
- data/spec/support/models/parent_doc.rb +1 -1
- data/spec/support/models/passport.rb +0 -1
- data/spec/support/models/patient.rb +2 -2
- data/spec/support/models/pdf_writer.rb +0 -1
- data/spec/support/models/pencil.rb +0 -1
- data/spec/support/models/person.rb +32 -28
- data/spec/support/models/pet.rb +1 -1
- data/spec/support/models/pet_owner.rb +1 -1
- data/spec/support/models/phone.rb +1 -2
- data/spec/support/models/piano.rb +0 -1
- data/spec/support/models/pizza.rb +1 -1
- data/spec/support/models/player.rb +5 -5
- data/spec/support/models/post.rb +12 -12
- data/spec/support/models/post_genre.rb +1 -1
- data/spec/support/models/powerup.rb +1 -2
- data/spec/support/models/preference.rb +2 -2
- data/spec/support/models/princess.rb +1 -1
- data/spec/support/models/product.rb +3 -3
- data/spec/support/models/profile.rb +2 -1
- data/spec/support/models/pronunciation.rb +1 -1
- data/spec/support/models/pub.rb +2 -2
- data/spec/support/models/publication/encyclopedia.rb +0 -1
- data/spec/support/models/publication/review.rb +0 -1
- data/spec/support/models/publication.rb +0 -1
- data/spec/support/models/purchase.rb +1 -1
- data/spec/support/models/purchased_item.rb +1 -1
- data/spec/support/models/question.rb +2 -2
- data/spec/support/models/quiz.rb +1 -1
- data/spec/support/models/rating.rb +1 -1
- data/spec/support/models/record.rb +2 -3
- data/spec/support/models/registry.rb +1 -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 +0 -1
- data/spec/support/models/sandbox/lib/models/lib_models_message.rb +0 -1
- data/spec/support/models/sandbox/sandbox_message.rb +0 -1
- data/spec/support/models/sandbox/sandbox_user.rb +0 -1
- data/spec/support/models/sandbox/subdir/sandbox_comment.rb +0 -1
- data/spec/support/models/sandwich.rb +1 -1
- data/spec/support/models/scheduler.rb +0 -1
- data/spec/support/models/school.rb +0 -1
- data/spec/support/models/scribe.rb +1 -1
- data/spec/support/models/sealer.rb +0 -1
- data/spec/support/models/seat.rb +0 -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 +2 -2
- data/spec/support/models/shape.rb +3 -3
- data/spec/support/models/shelf.rb +1 -1
- data/spec/support/models/shield.rb +2 -2
- data/spec/support/models/shipment_address.rb +0 -1
- data/spec/support/models/shipping_container.rb +1 -1
- data/spec/support/models/shipping_pack.rb +0 -1
- data/spec/support/models/shirt.rb +0 -1
- data/spec/support/models/shop.rb +2 -2
- data/spec/support/models/short_agent.rb +0 -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 -2
- data/spec/support/models/sound.rb +2 -2
- data/spec/support/models/spacer.rb +0 -1
- data/spec/support/models/square.rb +0 -1
- data/spec/support/models/staff.rb +0 -1
- data/spec/support/models/store_as_dup_test1.rb +2 -2
- data/spec/support/models/store_as_dup_test2.rb +1 -1
- data/spec/support/models/store_as_dup_test3.rb +2 -2
- data/spec/support/models/store_as_dup_test4.rb +1 -1
- data/spec/support/models/strategy.rb +0 -1
- data/spec/support/models/student.rb +1 -2
- data/spec/support/models/sub_item.rb +0 -1
- data/spec/support/models/subscription.rb +2 -2
- data/spec/support/models/survey.rb +2 -2
- data/spec/support/models/symptom.rb +2 -2
- data/spec/support/models/system_role.rb +2 -3
- data/spec/support/models/tag.rb +2 -2
- 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 +0 -1
- data/spec/support/models/title.rb +0 -1
- data/spec/support/models/tool.rb +3 -3
- data/spec/support/models/topping.rb +1 -1
- data/spec/support/models/toy.rb +0 -1
- data/spec/support/models/track.rb +1 -1
- data/spec/support/models/translation.rb +1 -1
- data/spec/support/models/tree.rb +2 -3
- data/spec/support/models/truck.rb +0 -1
- data/spec/support/models/updatable.rb +0 -1
- data/spec/support/models/user.rb +3 -4
- data/spec/support/models/user_account.rb +3 -3
- data/spec/support/models/validation_callback.rb +4 -4
- data/spec/support/models/vehicle.rb +2 -3
- data/spec/support/models/version.rb +1 -1
- data/spec/support/models/vertex.rb +0 -1
- data/spec/support/models/vet_visit.rb +1 -1
- data/spec/support/models/video.rb +2 -2
- data/spec/support/models/video_game.rb +0 -1
- data/spec/support/models/washer.rb +0 -1
- data/spec/support/models/weapon.rb +1 -2
- data/spec/support/models/wiki_page.rb +2 -3
- data/spec/support/models/word.rb +2 -2
- data/spec/support/models/word_origin.rb +1 -2
- data/spec/support/models/writer.rb +3 -3
- data/spec/support/rails_mock.rb +7 -12
- data/spec/support/shared/time.rb +0 -1
- data/spec/support/sinatra_mock.rb +4 -2
- data/spec/support/spec_config.rb +19 -18
- metadata +64 -2
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Association
|
|
5
|
+
module EagerLoad
|
|
6
|
+
# Something an eager load contributes to the pipeline, in the role it plays
|
|
7
|
+
# while the pipeline is built. A root is asked to contribute and the whole
|
|
8
|
+
# tree follows by recursion. AssociationInclusion stands for a single
|
|
9
|
+
# association; DiscriminatedInclusion stands for a name several subclasses
|
|
10
|
+
# share.
|
|
11
|
+
#
|
|
12
|
+
# @api private
|
|
13
|
+
class Inclusion
|
|
14
|
+
# Add this inclusion's stages to the destination.
|
|
15
|
+
#
|
|
16
|
+
# @param [ Array<Hash> ] destination The pipeline (or sub-pipeline) the
|
|
17
|
+
# stages are appended to.
|
|
18
|
+
# @param [ Array<Mongoid::Association::Relatable> ] chain The embedded path
|
|
19
|
+
# accumulated from the ancestors above this inclusion (empty at the top).
|
|
20
|
+
def contribute(destination, chain)
|
|
21
|
+
raise NotImplementedError
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# An inclusion that stands for a single association. The LookupPipeline holds
|
|
26
|
+
# the stage-building helpers the kinds lean on, and a node carries its own
|
|
27
|
+
# children, so the pipeline is built by recursion from the roots downward.
|
|
28
|
+
#
|
|
29
|
+
# @api private
|
|
30
|
+
class AssociationInclusion < Inclusion
|
|
31
|
+
class << self
|
|
32
|
+
# Builds the right kind of inclusion for the association. Each subclass
|
|
33
|
+
# decides whether it handles it (.for?); exactly one does.
|
|
34
|
+
#
|
|
35
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
36
|
+
# @param [ LookupPipeline ] pipeline The pipeline being built.
|
|
37
|
+
# @param [ Array<Inclusion> ] children The inclusions nested under it.
|
|
38
|
+
#
|
|
39
|
+
# @return [ AssociationInclusion ] The matching kind of inclusion.
|
|
40
|
+
def for(association, pipeline, children)
|
|
41
|
+
subclasses.find { |kind| kind.for?(association) }.new(association, pipeline, children)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Whether this kind handles the given association.
|
|
45
|
+
#
|
|
46
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
47
|
+
#
|
|
48
|
+
# @return [ true | false ] Whether it handles it.
|
|
49
|
+
def for?(association)
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# @return [ Mongoid::Association::Relatable ] The association this stands for.
|
|
55
|
+
attr_reader :association
|
|
56
|
+
|
|
57
|
+
def initialize(association, pipeline, children)
|
|
58
|
+
super()
|
|
59
|
+
@association = association
|
|
60
|
+
@pipeline = pipeline
|
|
61
|
+
@children = children
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# A referenced inclusion: contributes a $lookup whose sub-pipeline holds its
|
|
66
|
+
# own children. When it lives inside an embedded document (a non-empty
|
|
67
|
+
# chain), the $lookup is distributed onto that embedded path instead of
|
|
68
|
+
# standing at the top level.
|
|
69
|
+
#
|
|
70
|
+
# For a has_many :albums it contributes:
|
|
71
|
+
#
|
|
72
|
+
# { '$lookup' => {
|
|
73
|
+
# 'from' => 'albums',
|
|
74
|
+
# 'localField' => '_id', # the band's _id...
|
|
75
|
+
# 'foreignField' => 'band_id', # ...matched against each album's band_id
|
|
76
|
+
# 'as' => 'albums', # matches are written to this field
|
|
77
|
+
# 'pipeline' => [
|
|
78
|
+
# { '$sort' => {
|
|
79
|
+
# '_id' => 1
|
|
80
|
+
# } },
|
|
81
|
+
# <children>
|
|
82
|
+
# ]
|
|
83
|
+
# } }
|
|
84
|
+
#
|
|
85
|
+
# @api private
|
|
86
|
+
class JoinedInclusion < AssociationInclusion
|
|
87
|
+
class << self
|
|
88
|
+
# The default kind: a referenced, non-polymorphic association, i.e. the
|
|
89
|
+
# one no sibling kind claims.
|
|
90
|
+
#
|
|
91
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
92
|
+
#
|
|
93
|
+
# @return [ true | false ] Whether it handles it.
|
|
94
|
+
def for?(association)
|
|
95
|
+
(superclass.subclasses - [ self ]).none? { |kind| kind.for?(association) }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Append the $lookup, with the children in its sub-pipeline, to the
|
|
100
|
+
# destination; or distribute it onto the embedded path when nested in one.
|
|
101
|
+
#
|
|
102
|
+
# @param [ Array<Hash> ] destination The pipeline (or sub-pipeline) the
|
|
103
|
+
# stages are appended to.
|
|
104
|
+
# @param [ Array<Mongoid::Association::Relatable> ] chain The embedded path
|
|
105
|
+
# accumulated from the ancestors above this inclusion (empty at the top).
|
|
106
|
+
def contribute(destination, chain)
|
|
107
|
+
stage = @pipeline.lookup_stage_for(@association)
|
|
108
|
+
@children.each { |child| child.contribute(stage['$lookup']['pipeline'], []) }
|
|
109
|
+
|
|
110
|
+
if chain.empty?
|
|
111
|
+
destination << stage
|
|
112
|
+
else
|
|
113
|
+
destination.concat(@pipeline.distribute(@association, chain, stage))
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# An embedded inclusion: it rides inside its own document, so it adds no
|
|
119
|
+
# stage of its own. Its children contribute to the same destination, with
|
|
120
|
+
# this document appended to their embedded path.
|
|
121
|
+
#
|
|
122
|
+
# For Computer.eager_load(port: :device) the :port inclusion emits nothing;
|
|
123
|
+
# it hands the path [ :port ] to :device, which EmbeddedDistributor then
|
|
124
|
+
# turns into stages.
|
|
125
|
+
#
|
|
126
|
+
# @api private
|
|
127
|
+
class EmbeddedInclusion < AssociationInclusion
|
|
128
|
+
class << self
|
|
129
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
130
|
+
#
|
|
131
|
+
# @return [ true | false ] Whether the association is embedded.
|
|
132
|
+
def for?(association)
|
|
133
|
+
association.embedded?
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# Add no stage of its own; hand this document down the embedded path so the
|
|
138
|
+
# children distribute onto it.
|
|
139
|
+
#
|
|
140
|
+
# @param [ Array<Hash> ] destination The pipeline (or sub-pipeline) the
|
|
141
|
+
# stages are appended to.
|
|
142
|
+
# @param [ Array<Mongoid::Association::Relatable> ] chain The embedded path
|
|
143
|
+
# accumulated from the ancestors above this inclusion (empty at the top).
|
|
144
|
+
def contribute(destination, chain)
|
|
145
|
+
@children.each { |child| child.contribute(destination, chain + [ @association ]) }
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# A polymorphic inclusion: its target collection varies per document, so it
|
|
150
|
+
# can't be a $lookup. It adds nothing here; PolymorphicPreloader resolves it
|
|
151
|
+
# after the roots are materialized.
|
|
152
|
+
#
|
|
153
|
+
# @api private
|
|
154
|
+
class DeferredInclusion < AssociationInclusion
|
|
155
|
+
class << self
|
|
156
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
157
|
+
#
|
|
158
|
+
# @return [ true | false ] Whether the association is polymorphic.
|
|
159
|
+
def for?(association)
|
|
160
|
+
association.polymorphic?
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# Add nothing; PolymorphicPreloader resolves the association after the
|
|
165
|
+
# roots are materialized.
|
|
166
|
+
#
|
|
167
|
+
# @param [ Array<Hash> ] destination The pipeline (unused).
|
|
168
|
+
# @param [ Array<Mongoid::Association::Relatable> ] chain The embedded path (unused).
|
|
169
|
+
def contribute(destination, chain); end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
end
|
|
173
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mongoid/association/eager_load/discriminated_inclusion'
|
|
4
|
+
require 'mongoid/association/eager_load/inclusion'
|
|
5
|
+
|
|
6
|
+
module Mongoid
|
|
7
|
+
module Association
|
|
8
|
+
module EagerLoad
|
|
9
|
+
# The tree of nested inclusions an eager load asks to load. Built from the
|
|
10
|
+
# criteria's inclusions, it contributes each root node's stages to the
|
|
11
|
+
# pipeline, with each node already carrying its own children.
|
|
12
|
+
#
|
|
13
|
+
# Each root branch is built from its own copy of the inclusions, and an
|
|
14
|
+
# inclusion is removed as it is placed, so it lands once per branch even if
|
|
15
|
+
# more than one parent in that branch points at it, and a circular chain of
|
|
16
|
+
# inclusions can't loop forever.
|
|
17
|
+
#
|
|
18
|
+
# @api private
|
|
19
|
+
class InclusionTree
|
|
20
|
+
class << self
|
|
21
|
+
# Builds the tree for the criteria's inclusions.
|
|
22
|
+
#
|
|
23
|
+
# @param [ Array<Mongoid::Association::Relatable> ] inclusions The inclusions.
|
|
24
|
+
# @param [ LookupPipeline ] pipeline The pipeline being built.
|
|
25
|
+
#
|
|
26
|
+
# @return [ InclusionTree ] The tree.
|
|
27
|
+
def from(inclusions, pipeline)
|
|
28
|
+
new(inclusions, pipeline, inclusions.to_h { |association| [ association.name, association ] })
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private :new
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize(inclusions, pipeline, by_name)
|
|
35
|
+
@inclusions = inclusions
|
|
36
|
+
@pipeline = pipeline
|
|
37
|
+
@by_name = by_name
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Contribute each root inclusion's stages to the pipeline. Each root carries
|
|
41
|
+
# its own children, so the whole tree is appended by recursion from the
|
|
42
|
+
# roots downward.
|
|
43
|
+
#
|
|
44
|
+
# @param [ Array<Hash> ] destination The pipeline the stages are appended to.
|
|
45
|
+
def contribute_to(destination)
|
|
46
|
+
roots.each { |root| root.contribute(destination, []) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
private
|
|
50
|
+
|
|
51
|
+
# A name that more than one subclass defines (with different targets) can't
|
|
52
|
+
# share one $lookup field, so its nodes -- each carrying its own children --
|
|
53
|
+
# are grouped and routed by the discriminator instead of becoming separate,
|
|
54
|
+
# overwriting roots.
|
|
55
|
+
def roots
|
|
56
|
+
top_level.group_by(&:name).map do |_name, associations|
|
|
57
|
+
nodes = associations.map { |association| node(association, @inclusions.dup) }
|
|
58
|
+
nodes.one? ? nodes.first : DiscriminatedInclusion.new(nodes)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The inclusions that no other inclusion is the parent of.
|
|
63
|
+
def top_level
|
|
64
|
+
@inclusions.reject do |association|
|
|
65
|
+
association.parent_inclusions.any? { |name| @by_name.key?(name) }
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def node(association, available)
|
|
70
|
+
children = take_children(association, available).map { |child| node(child, available) }
|
|
71
|
+
AssociationInclusion.for(association, @pipeline, children)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# The still-available inclusions parented to +association+, removed as they
|
|
75
|
+
# are taken so each lands once on this branch. A child belongs here when it
|
|
76
|
+
# names this association as its parent and its owner shares the target's
|
|
77
|
+
# class hierarchy, which tells apart children of two unrelated subclasses
|
|
78
|
+
# that share an association name.
|
|
79
|
+
def take_children(association, available)
|
|
80
|
+
children = available.select do |candidate|
|
|
81
|
+
candidate.parent_inclusions.include?(association.name) &&
|
|
82
|
+
same_hierarchy?(association.klass, candidate.inverse_class)
|
|
83
|
+
end
|
|
84
|
+
available.reject! { |candidate| children.include?(candidate) }
|
|
85
|
+
children
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Whether two classes belong to the same inheritance chain (one is the
|
|
89
|
+
# other, an ancestor of it, or a descendant of it).
|
|
90
|
+
def same_hierarchy?(one, other)
|
|
91
|
+
one <= other || other <= one
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mongoid/association/eager_load/embedded_distributor'
|
|
4
|
+
require 'mongoid/association/eager_load/inclusion_tree'
|
|
5
|
+
|
|
6
|
+
module Mongoid
|
|
7
|
+
module Association
|
|
8
|
+
module EagerLoad
|
|
9
|
+
# Builds the aggregation pipeline that eager-loads a criteria's inclusions
|
|
10
|
+
# with $lookup.
|
|
11
|
+
#
|
|
12
|
+
# It starts with the criteria's own match/sort/skip/limit, then lets each
|
|
13
|
+
# root of the inclusion tree contribute its stages. This object owns the
|
|
14
|
+
# stage-building helpers; how each inclusion contributes is the inclusion's
|
|
15
|
+
# own business (see Inclusion).
|
|
16
|
+
#
|
|
17
|
+
# For Band.eager_load(albums: :tracks) the result is roughly:
|
|
18
|
+
#
|
|
19
|
+
# [ <criteria match / sort / skip / limit>,
|
|
20
|
+
# { '$lookup' => { # JoinedInclusion(:albums)
|
|
21
|
+
# 'from' => 'albums',
|
|
22
|
+
# 'localField' => '_id',
|
|
23
|
+
# 'foreignField' => 'band_id',
|
|
24
|
+
# 'as' => 'albums',
|
|
25
|
+
# 'pipeline' => [
|
|
26
|
+
# { '$sort' => {
|
|
27
|
+
# '_id' => 1
|
|
28
|
+
# } },
|
|
29
|
+
# { '$lookup' => { # JoinedInclusion(:tracks), nested
|
|
30
|
+
# 'as' => 'tracks',
|
|
31
|
+
# 'pipeline' => [
|
|
32
|
+
# { '$sort' => {
|
|
33
|
+
# '_id' => 1
|
|
34
|
+
# } }
|
|
35
|
+
# ]
|
|
36
|
+
# } }
|
|
37
|
+
# ]
|
|
38
|
+
# } } ]
|
|
39
|
+
#
|
|
40
|
+
# @api private
|
|
41
|
+
class LookupPipeline
|
|
42
|
+
def initialize(criteria)
|
|
43
|
+
@criteria = criteria
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# @return [ Array<Hash> ] The aggregation pipeline stages.
|
|
47
|
+
def stages
|
|
48
|
+
pipeline = @criteria.selector.to_pipeline
|
|
49
|
+
pipeline.concat(@criteria.options.to_pipeline_for_lookup)
|
|
50
|
+
InclusionTree.from(@criteria.inclusions, self).contribute_to(pipeline)
|
|
51
|
+
pipeline
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# The $lookup stage for a referenced inclusion: its key fields, a
|
|
55
|
+
# discriminator match when the target shares its collection with sibling
|
|
56
|
+
# subclasses, and an order. Children are added by the inclusion itself.
|
|
57
|
+
#
|
|
58
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
59
|
+
#
|
|
60
|
+
# @return [ Hash ] The $lookup stage.
|
|
61
|
+
def lookup_stage_for(association)
|
|
62
|
+
local_field, foreign_field = lookup_fields(association)
|
|
63
|
+
sub_pipeline = []
|
|
64
|
+
sub_pipeline << discriminator_match(association) if association.klass.hereditary?
|
|
65
|
+
sub_pipeline << order(association)
|
|
66
|
+
{ '$lookup' => {
|
|
67
|
+
'from' => association.klass.collection.name,
|
|
68
|
+
'localField' => local_field,
|
|
69
|
+
'foreignField' => foreign_field,
|
|
70
|
+
'as' => association.name.to_s,
|
|
71
|
+
'pipeline' => sub_pipeline
|
|
72
|
+
} }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Builds the stages that distribute a referenced inclusion living inside an
|
|
76
|
+
# embedded document onto that document.
|
|
77
|
+
#
|
|
78
|
+
# @param [ Mongoid::Association::Relatable ] association The inclusion.
|
|
79
|
+
# @param [ Array<Mongoid::Association::Relatable> ] chain The embedded path.
|
|
80
|
+
# @param [ Hash ] lookup_stage The $lookup stage for the association.
|
|
81
|
+
#
|
|
82
|
+
# @return [ Array<Hash> ] The stages to append.
|
|
83
|
+
def distribute(association, chain, lookup_stage)
|
|
84
|
+
EmbeddedDistributor.for(association: association, chain: chain, lookup_stage: lookup_stage).stages
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
private
|
|
88
|
+
|
|
89
|
+
# When the association stores the foreign key on the current document
|
|
90
|
+
# (belongs_to, has_and_belongs_to_many) the local field is that key; for
|
|
91
|
+
# the others (has_many, has_one) the key is on the related document.
|
|
92
|
+
def lookup_fields(association)
|
|
93
|
+
if association.stores_foreign_key?
|
|
94
|
+
[ association.foreign_key, association.primary_key ]
|
|
95
|
+
else
|
|
96
|
+
[ association.primary_key, association.foreign_key ]
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def discriminator_match(association)
|
|
101
|
+
target = association.klass
|
|
102
|
+
{ '$match' => {
|
|
103
|
+
target.discriminator_key => { '$in' => target._types }
|
|
104
|
+
} }
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def order(association)
|
|
108
|
+
unless association.order
|
|
109
|
+
return { '$sort' => {
|
|
110
|
+
'_id' => 1
|
|
111
|
+
} }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
ordering = association.order
|
|
115
|
+
ordering = { ordering => 1 } unless ordering.is_a?(Hash)
|
|
116
|
+
{ '$sort' => ordering }
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'mongoid/association/eager_load/polymorphic_targets'
|
|
4
|
+
|
|
5
|
+
module Mongoid
|
|
6
|
+
module Association
|
|
7
|
+
module EagerLoad
|
|
8
|
+
# Resolves a polymorphic belongs_to onto already-materialized root documents.
|
|
9
|
+
#
|
|
10
|
+
# A polymorphic belongs_to can't be expressed as a $lookup: its target
|
|
11
|
+
# collection varies per document. So once the roots are materialized, the
|
|
12
|
+
# foreign keys are grouped by type, PolymorphicTargets resolves the documents
|
|
13
|
+
# for those keys, and the result is set on each document.
|
|
14
|
+
#
|
|
15
|
+
# @api private
|
|
16
|
+
class PolymorphicPreloader
|
|
17
|
+
def initialize(association, root_class)
|
|
18
|
+
@association = association
|
|
19
|
+
@root_class = root_class
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# Resolve and assign the polymorphic target on each of the documents.
|
|
23
|
+
#
|
|
24
|
+
# @param [ Array<Mongoid::Document> ] documents The materialized root documents.
|
|
25
|
+
def preload_into(documents)
|
|
26
|
+
targets = PolymorphicTargets.for(@association, keys_by_type(documents), @root_class)
|
|
27
|
+
assign(documents, targets)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
# The foreign keys on the documents grouped by polymorphic type,
|
|
33
|
+
# e.g. { "Printer" => [ id1 ], "Scanner" => [ id2 ] }.
|
|
34
|
+
def keys_by_type(documents)
|
|
35
|
+
documents.each_with_object({}) do |document, grouped|
|
|
36
|
+
type, key = reference_on(document)
|
|
37
|
+
(grouped[type] ||= []) << key if type && key
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def assign(documents, targets)
|
|
42
|
+
documents.each do |document|
|
|
43
|
+
type, key = reference_on(document)
|
|
44
|
+
target = targets.dig(type, key) if type && key
|
|
45
|
+
document.set_relation(@association.name, target)
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The [ type, key ] reference stored on the document for this association,
|
|
50
|
+
# or an empty pair when the document holds no such reference.
|
|
51
|
+
def reference_on(document)
|
|
52
|
+
type_field = @association.inverse_type
|
|
53
|
+
key_field = @association.foreign_key
|
|
54
|
+
return [] unless document.respond_to?(type_field) && document.respond_to?(key_field)
|
|
55
|
+
|
|
56
|
+
[ document.send(type_field), document.send(key_field) ]
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mongoid
|
|
4
|
+
module Association
|
|
5
|
+
module EagerLoad
|
|
6
|
+
# The targets of a polymorphic belongs_to, indexed as
|
|
7
|
+
# { type => { primary_key => document } }. Each subclass reaches the types that
|
|
8
|
+
# live in one place (the root's database or elsewhere); .for resolves the whole
|
|
9
|
+
# set, routing each type to the subclass that can reach it.
|
|
10
|
+
#
|
|
11
|
+
# @api private
|
|
12
|
+
class PolymorphicTargets
|
|
13
|
+
class << self
|
|
14
|
+
# Resolve every polymorphic target for the foreign keys grouped by type.
|
|
15
|
+
# The types whose documents share the root's database are fetched together
|
|
16
|
+
# in one $facet; those living elsewhere are read through their own models.
|
|
17
|
+
#
|
|
18
|
+
# @param [ Mongoid::Association::Relatable ] association The polymorphic inclusion.
|
|
19
|
+
# @param [ Hash ] keys_by_type The foreign keys grouped by type.
|
|
20
|
+
# @param [ Class ] root_class The class being queried.
|
|
21
|
+
#
|
|
22
|
+
# @return [ Hash ] The targets, as { type => { primary_key => document } }.
|
|
23
|
+
def for(association, keys_by_type, root_class)
|
|
24
|
+
here, elsewhere = keys_by_type.partition do |type, _keys|
|
|
25
|
+
in_root_database?(association, type, root_class)
|
|
26
|
+
end
|
|
27
|
+
same_database = SameDatabaseTargets.new(association, here.to_h, root_class)
|
|
28
|
+
other_databases = OtherDatabaseTargets.new(association, elsewhere.to_h)
|
|
29
|
+
same_database.fetch.merge(other_databases.fetch)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
# Whether the type's model shares the root's database (and client): exactly
|
|
35
|
+
# what a $lookup from the root collection can reach.
|
|
36
|
+
def in_root_database?(association, type, root_class)
|
|
37
|
+
model = association.resolver.model_for(type)
|
|
38
|
+
model.client_name == root_class.client_name &&
|
|
39
|
+
model.database_name == root_class.database_name
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def initialize(association, keys_by_type)
|
|
44
|
+
@association = association
|
|
45
|
+
@keys_by_type = keys_by_type
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @return [ Hash ] The targets, as { type => { primary_key => document } }.
|
|
49
|
+
def fetch
|
|
50
|
+
raise NotImplementedError
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
def primary_key
|
|
56
|
+
@association.primary_key
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def model_for(type)
|
|
60
|
+
@association.resolver.model_for(type)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The raw documents instantiated and indexed by their primary key.
|
|
64
|
+
def indexed(documents, model)
|
|
65
|
+
documents.map { |document| Factory.from_db(model, document) }
|
|
66
|
+
.index_by { |document| document.send(primary_key) }
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Targets that live in the root's own database. A $lookup can reach them, so
|
|
71
|
+
# every type is fetched together in one $facet aggregation against the root
|
|
72
|
+
# collection.
|
|
73
|
+
#
|
|
74
|
+
# For { 'Printer' => [ id1 ], 'Scanner' => [ id2 ] } it runs:
|
|
75
|
+
#
|
|
76
|
+
# [
|
|
77
|
+
# { '$limit' => 1 }, # one input doc, so each facet branch runs once
|
|
78
|
+
# { '$facet' => { # run one $lookup per type within a single query
|
|
79
|
+
# 'Printer' => [ { '$lookup' => { 'from' => 'printers', ... } }, ... ],
|
|
80
|
+
# 'Scanner' => [ { '$lookup' => { 'from' => 'scanners', ... } }, ... ]
|
|
81
|
+
# } }
|
|
82
|
+
# ]
|
|
83
|
+
#
|
|
84
|
+
# @api private
|
|
85
|
+
class SameDatabaseTargets < PolymorphicTargets
|
|
86
|
+
def initialize(association, keys_by_type, root_class)
|
|
87
|
+
super(association, keys_by_type)
|
|
88
|
+
@root_class = root_class
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# @return [ Hash ] The targets, as { type => { primary_key => document } }.
|
|
92
|
+
def fetch
|
|
93
|
+
return {} if @keys_by_type.empty?
|
|
94
|
+
|
|
95
|
+
aggregated = @root_class.collection.aggregate([ { '$limit' => 1 }, { '$facet' => facets } ]).first
|
|
96
|
+
aggregated.to_h do |type, branch|
|
|
97
|
+
# $limit => 1 makes each branch yield a single wrapper holding the matches.
|
|
98
|
+
[ type, indexed(branch.first['matches'], model_for(type)) ]
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
private
|
|
103
|
+
|
|
104
|
+
def facets
|
|
105
|
+
@keys_by_type.to_h do |type, keys|
|
|
106
|
+
[ type, branch_for(model_for(type).collection.name, keys) ]
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# One $facet branch: the documents in +collection_name+ whose primary key
|
|
111
|
+
# is among +keys+, exposed under "matches".
|
|
112
|
+
def branch_for(collection_name, keys)
|
|
113
|
+
[
|
|
114
|
+
{ '$lookup' => {
|
|
115
|
+
'from' => collection_name,
|
|
116
|
+
'pipeline' => [
|
|
117
|
+
{ '$match' => {
|
|
118
|
+
primary_key => { '$in' => keys.uniq }
|
|
119
|
+
} }
|
|
120
|
+
],
|
|
121
|
+
'as' => 'matches'
|
|
122
|
+
} },
|
|
123
|
+
{ '$project' => {
|
|
124
|
+
'_id' => 0,
|
|
125
|
+
'matches' => 1
|
|
126
|
+
} }
|
|
127
|
+
]
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Targets kept in another database (or cluster), which a $lookup cannot
|
|
132
|
+
# reach. Each type is read directly through its own model, which connects
|
|
133
|
+
# with that model's client.
|
|
134
|
+
#
|
|
135
|
+
# For { 'Scanner' => [ id2 ] } it runs, on the Scanner model's own client:
|
|
136
|
+
# scanners.find('_id' => { '$in' => [ id2 ] })
|
|
137
|
+
#
|
|
138
|
+
# @api private
|
|
139
|
+
class OtherDatabaseTargets < PolymorphicTargets
|
|
140
|
+
# @return [ Hash ] The targets, as { type => { primary_key => document } }.
|
|
141
|
+
def fetch
|
|
142
|
+
@keys_by_type.to_h do |type, keys|
|
|
143
|
+
model = model_for(type)
|
|
144
|
+
documents = model.collection.find(primary_key => { '$in' => keys.uniq })
|
|
145
|
+
[ type, indexed(documents, model) ]
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|