mongoid 7.4.3 → 8.0.7
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/README.md +3 -3
- data/Rakefile +25 -0
- data/lib/config/locales/en.yml +52 -28
- data/lib/mongoid/association/accessors.rb +38 -9
- data/lib/mongoid/association/bindable.rb +50 -2
- data/lib/mongoid/association/builders.rb +4 -2
- data/lib/mongoid/association/constrainable.rb +0 -1
- data/lib/mongoid/association/eager_loadable.rb +29 -7
- data/lib/mongoid/association/embedded/batchable.rb +33 -10
- data/lib/mongoid/association/embedded/cyclic.rb +1 -1
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +24 -2
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -2
- data/lib/mongoid/association/embedded/embedded_in.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +65 -41
- data/lib/mongoid/association/embedded/embeds_many.rb +2 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +18 -4
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +23 -4
- data/lib/mongoid/association/embedded/embeds_one.rb +3 -3
- data/lib/mongoid/association/macros.rb +28 -1
- data/lib/mongoid/association/many.rb +11 -7
- data/lib/mongoid/association/nested/many.rb +5 -4
- data/lib/mongoid/association/nested/nested_buildable.rb +4 -4
- data/lib/mongoid/association/nested/one.rb +5 -5
- data/lib/mongoid/association/one.rb +2 -2
- data/lib/mongoid/association/options.rb +9 -9
- data/lib/mongoid/association/proxy.rb +14 -3
- data/lib/mongoid/association/referenced/auto_save.rb +4 -3
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +5 -6
- data/lib/mongoid/association/referenced/belongs_to.rb +2 -2
- data/lib/mongoid/association/referenced/counter_cache.rb +10 -10
- data/lib/mongoid/association/referenced/eager.rb +2 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +70 -13
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +6 -3
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +20 -24
- data/lib/mongoid/association/referenced/has_many/proxy.rb +26 -16
- data/lib/mongoid/association/referenced/has_many.rb +3 -3
- data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +5 -5
- data/lib/mongoid/association/referenced/has_one/proxy.rb +9 -12
- data/lib/mongoid/association/referenced/has_one.rb +3 -3
- data/lib/mongoid/association/referenced/syncable.rb +4 -4
- data/lib/mongoid/association/reflections.rb +2 -2
- data/lib/mongoid/association/relatable.rb +44 -10
- data/lib/mongoid/association.rb +5 -5
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +7 -0
- data/lib/mongoid/attributes/dynamic.rb +3 -3
- data/lib/mongoid/attributes/nested.rb +5 -5
- data/lib/mongoid/attributes/processing.rb +37 -6
- data/lib/mongoid/attributes/projector.rb +1 -1
- data/lib/mongoid/attributes/readonly.rb +2 -2
- data/lib/mongoid/attributes.rb +43 -40
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/changeable.rb +43 -10
- data/lib/mongoid/clients/options.rb +5 -1
- data/lib/mongoid/clients/sessions.rb +2 -14
- data/lib/mongoid/clients/validators/storage.rb +3 -3
- data/lib/mongoid/config/options.rb +3 -0
- data/lib/mongoid/config/validators/client.rb +6 -6
- data/lib/mongoid/config.rb +62 -17
- data/lib/mongoid/contextual/aggregable/memory.rb +24 -16
- data/lib/mongoid/contextual/aggregable/mongo.rb +5 -5
- data/lib/mongoid/contextual/aggregable/none.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +1 -1
- data/lib/mongoid/contextual/geo_near.rb +7 -7
- data/lib/mongoid/contextual/map_reduce.rb +2 -2
- data/lib/mongoid/contextual/memory.rb +180 -21
- data/lib/mongoid/contextual/mongo.rb +260 -217
- data/lib/mongoid/contextual/none.rb +67 -5
- data/lib/mongoid/contextual/queryable.rb +1 -1
- data/lib/mongoid/contextual.rb +2 -2
- data/lib/mongoid/copyable.rb +32 -8
- data/lib/mongoid/criteria/findable.rb +7 -4
- data/lib/mongoid/criteria/includable.rb +24 -20
- data/lib/mongoid/criteria/marshalable.rb +10 -2
- data/lib/mongoid/criteria/permission.rb +1 -1
- data/lib/mongoid/criteria/queryable/aggregable.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/array.rb +3 -14
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +25 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -2
- data/lib/mongoid/criteria/queryable/extensions/date.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +1 -15
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -9
- data/lib/mongoid/criteria/queryable/extensions/object.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +13 -5
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
- data/lib/mongoid/criteria/queryable/extensions/set.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/string.rb +4 -14
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +4 -12
- data/lib/mongoid/criteria/queryable/extensions/time.rb +6 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +6 -1
- data/lib/mongoid/criteria/queryable/key.rb +3 -3
- data/lib/mongoid/criteria/queryable/mergeable.rb +21 -0
- data/lib/mongoid/criteria/queryable/optional.rb +5 -11
- data/lib/mongoid/criteria/queryable/options.rb +2 -2
- data/lib/mongoid/criteria/queryable/pipeline.rb +1 -1
- data/lib/mongoid/criteria/queryable/selectable.rb +31 -37
- data/lib/mongoid/criteria/queryable/selector.rb +93 -8
- data/lib/mongoid/criteria/queryable/smash.rb +40 -7
- data/lib/mongoid/criteria/queryable/storable.rb +1 -1
- data/lib/mongoid/criteria/queryable.rb +12 -7
- data/lib/mongoid/criteria/scopable.rb +2 -2
- data/lib/mongoid/criteria/translator.rb +45 -0
- data/lib/mongoid/criteria.rb +16 -35
- data/lib/mongoid/deprecable.rb +37 -0
- data/lib/mongoid/deprecation.rb +25 -0
- data/lib/mongoid/document.rb +135 -34
- data/lib/mongoid/equality.rb +8 -8
- data/lib/mongoid/errors/document_not_found.rb +33 -12
- data/lib/mongoid/errors/invalid_config_option.rb +1 -1
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -1
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +23 -0
- data/lib/mongoid/errors/invalid_field.rb +6 -2
- data/lib/mongoid/errors/invalid_field_type.rb +26 -0
- data/lib/mongoid/errors/invalid_relation.rb +1 -1
- data/lib/mongoid/errors/invalid_relation_option.rb +1 -1
- data/lib/mongoid/errors/invalid_session_use.rb +1 -1
- data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
- data/lib/mongoid/errors/mongoid_error.rb +3 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -1
- data/lib/mongoid/errors/no_client_database.rb +1 -1
- data/lib/mongoid/errors/no_client_hosts.rb +1 -1
- data/lib/mongoid/errors/readonly_attribute.rb +1 -1
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -1
- data/lib/mongoid/errors/unknown_attribute.rb +1 -1
- data/lib/mongoid/errors.rb +2 -2
- data/lib/mongoid/extensions/array.rb +9 -7
- data/lib/mongoid/extensions/big_decimal.rb +33 -10
- data/lib/mongoid/extensions/binary.rb +42 -0
- data/lib/mongoid/extensions/boolean.rb +8 -2
- data/lib/mongoid/extensions/date.rb +26 -20
- data/lib/mongoid/extensions/date_time.rb +1 -1
- data/lib/mongoid/extensions/false_class.rb +1 -1
- data/lib/mongoid/extensions/float.rb +7 -4
- data/lib/mongoid/extensions/hash.rb +37 -8
- data/lib/mongoid/extensions/integer.rb +7 -4
- data/lib/mongoid/extensions/module.rb +1 -1
- data/lib/mongoid/extensions/object.rb +8 -6
- data/lib/mongoid/extensions/range.rb +41 -10
- data/lib/mongoid/extensions/regexp.rb +11 -4
- data/lib/mongoid/extensions/set.rb +11 -4
- data/lib/mongoid/extensions/string.rb +11 -22
- data/lib/mongoid/extensions/symbol.rb +4 -15
- data/lib/mongoid/extensions/time.rb +27 -16
- data/lib/mongoid/extensions/time_with_zone.rb +1 -2
- data/lib/mongoid/extensions/true_class.rb +1 -1
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/factory.rb +55 -7
- data/lib/mongoid/fields/foreign_key.rb +11 -4
- data/lib/mongoid/fields/localized.rb +9 -4
- data/lib/mongoid/fields/standard.rb +7 -7
- data/lib/mongoid/fields/validators/macro.rb +3 -9
- data/lib/mongoid/fields.rb +233 -40
- data/lib/mongoid/findable.rb +34 -13
- data/lib/mongoid/indexable/specification.rb +2 -2
- data/lib/mongoid/indexable/validators/options.rb +6 -2
- data/lib/mongoid/interceptable.rb +185 -16
- data/lib/mongoid/matchable.rb +1 -1
- data/lib/mongoid/matcher.rb +33 -13
- data/lib/mongoid/persistable/creatable.rb +18 -9
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/persistable/destroyable.rb +1 -1
- data/lib/mongoid/persistable/savable.rb +2 -2
- data/lib/mongoid/persistable/unsettable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +19 -12
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/persistable.rb +3 -3
- data/lib/mongoid/persistence_context.rb +63 -10
- data/lib/mongoid/query_cache.rb +8 -260
- data/lib/mongoid/railties/controller_runtime.rb +1 -1
- data/lib/mongoid/reloadable.rb +10 -8
- data/lib/mongoid/scopable.rb +26 -22
- data/lib/mongoid/selectable.rb +1 -2
- data/lib/mongoid/serializable.rb +10 -6
- data/lib/mongoid/shardable.rb +35 -11
- data/lib/mongoid/stateful.rb +35 -9
- data/lib/mongoid/tasks/database.rb +0 -2
- data/lib/mongoid/threaded/lifecycle.rb +5 -5
- data/lib/mongoid/threaded.rb +42 -12
- data/lib/mongoid/timestamps/created.rb +1 -1
- data/lib/mongoid/timestamps/updated.rb +2 -2
- data/lib/mongoid/touchable.rb +2 -3
- data/lib/mongoid/traversable.rb +5 -4
- data/lib/mongoid/validatable/localizable.rb +1 -1
- data/lib/mongoid/validatable/macros.rb +0 -2
- data/lib/mongoid/validatable/presence.rb +2 -2
- data/lib/mongoid/validatable/uniqueness.rb +9 -8
- data/lib/mongoid/validatable.rb +6 -6
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid/warnings.rb +28 -0
- data/lib/mongoid.rb +2 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +4 -3
- data/spec/config/mongoid.yml +16 -0
- data/spec/integration/app_spec.rb +8 -12
- data/spec/integration/associations/belongs_to_spec.rb +18 -0
- data/spec/integration/associations/embedded_spec.rb +15 -0
- data/spec/integration/associations/embeds_many_spec.rb +15 -2
- data/spec/integration/associations/embeds_one_spec.rb +18 -0
- data/spec/integration/associations/foreign_key_spec.rb +9 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +21 -0
- data/spec/integration/associations/has_one_spec.rb +97 -1
- data/spec/integration/associations/scope_option_spec.rb +1 -1
- data/spec/integration/callbacks_models.rb +95 -1
- data/spec/integration/callbacks_spec.rb +246 -4
- data/spec/integration/criteria/range_spec.rb +95 -1
- data/spec/integration/discriminator_key_spec.rb +115 -76
- data/spec/integration/dots_and_dollars_spec.rb +277 -0
- data/spec/integration/i18n_fallbacks_spec.rb +1 -17
- data/spec/integration/matcher_examples_spec.rb +20 -13
- data/spec/integration/matcher_operator_data/type_decimal.yml +3 -2
- data/spec/integration/matcher_operator_spec.rb +3 -5
- data/spec/integration/persistence/range_field_spec.rb +350 -0
- data/spec/mongoid/association/counter_cache_spec.rb +1 -1
- data/spec/mongoid/association/depending_spec.rb +9 -9
- data/spec/mongoid/association/eager_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +54 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +69 -9
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +112 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +235 -40
- data/spec/mongoid/association/embedded/embeds_many_models.rb +36 -0
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +12 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +68 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +25 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +28 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +2 -1
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +54 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +15 -0
- data/spec/mongoid/association/referenced/belongs_to_models.rb +11 -0
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +202 -201
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +25 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +35 -2
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +109 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +8 -8
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +160 -119
- data/spec/mongoid/association/referenced/has_many_models.rb +3 -1
- data/spec/mongoid/association/referenced/has_many_spec.rb +25 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +2 -2
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +107 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +16 -0
- data/spec/mongoid/association/syncable_spec.rb +14 -0
- data/spec/mongoid/atomic/paths_spec.rb +0 -14
- data/spec/mongoid/attributes/nested_spec.rb +80 -11
- data/spec/mongoid/attributes/nested_spec_models.rb +48 -0
- data/spec/mongoid/attributes/projector_spec.rb +1 -5
- data/spec/mongoid/attributes_spec.rb +551 -27
- data/spec/mongoid/cacheable_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +130 -13
- data/spec/mongoid/clients/factory_spec.rb +23 -30
- data/spec/mongoid/clients/options_spec.rb +1 -0
- data/spec/mongoid/clients/sessions_spec.rb +0 -38
- data/spec/mongoid/clients_spec.rb +57 -2
- data/spec/mongoid/config_spec.rb +78 -18
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +396 -158
- data/spec/mongoid/contextual/aggregable/memory_table.yml +88 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +62 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +2 -16
- data/spec/mongoid/contextual/memory_spec.rb +1336 -69
- data/spec/mongoid/contextual/mongo_spec.rb +1253 -247
- data/spec/mongoid/contextual/none_spec.rb +38 -0
- data/spec/mongoid/copyable_spec.rb +451 -1
- data/spec/mongoid/criteria/findable_spec.rb +86 -210
- data/spec/mongoid/criteria/includable_spec.rb +1492 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +54 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +18 -1
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +7 -19
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +134 -26
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +0 -15
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +73 -7
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +0 -59
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +11 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +15 -484
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +50 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +289 -124
- data/spec/mongoid/criteria/queryable/selector_spec.rb +89 -4
- data/spec/mongoid/criteria/queryable/storable_spec.rb +72 -0
- data/spec/mongoid/criteria/translator_spec.rb +132 -0
- data/spec/mongoid/criteria_projection_spec.rb +0 -1
- data/spec/mongoid/criteria_spec.rb +475 -1199
- data/spec/mongoid/document_fields_spec.rb +173 -24
- data/spec/mongoid/document_spec.rb +32 -41
- data/spec/mongoid/errors/document_not_found_spec.rb +76 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +1 -1
- data/spec/mongoid/errors/invalid_field_type_spec.rb +55 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +3 -1
- data/spec/mongoid/errors/no_environment_spec.rb +3 -3
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -1
- data/spec/mongoid/extensions/array_spec.rb +16 -2
- data/spec/mongoid/extensions/big_decimal_spec.rb +712 -212
- data/spec/mongoid/extensions/binary_spec.rb +44 -9
- data/spec/mongoid/extensions/boolean_spec.rb +68 -82
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +7 -3
- data/spec/mongoid/extensions/date_spec.rb +71 -1
- data/spec/mongoid/extensions/date_time_spec.rb +15 -9
- data/spec/mongoid/extensions/float_spec.rb +53 -74
- data/spec/mongoid/extensions/hash_spec.rb +33 -3
- data/spec/mongoid/extensions/integer_spec.rb +50 -64
- data/spec/mongoid/extensions/range_spec.rb +255 -54
- data/spec/mongoid/extensions/regexp_spec.rb +58 -33
- data/spec/mongoid/extensions/set_spec.rb +106 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -25
- data/spec/mongoid/extensions/symbol_spec.rb +18 -25
- data/spec/mongoid/extensions/time_spec.rb +634 -66
- data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -31
- data/spec/mongoid/factory_spec.rb +61 -1
- data/spec/mongoid/fields/localized_spec.rb +37 -12
- data/spec/mongoid/fields_spec.rb +364 -50
- data/spec/mongoid/findable_spec.rb +80 -15
- data/spec/mongoid/indexable/specification_spec.rb +2 -2
- data/spec/mongoid/indexable_spec.rb +39 -20
- data/spec/mongoid/interceptable_spec.rb +807 -27
- data/spec/mongoid/interceptable_spec_models.rb +235 -4
- data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -5
- data/spec/mongoid/mongoizable_spec.rb +285 -0
- data/spec/mongoid/persistable/creatable_spec.rb +2 -2
- data/spec/mongoid/persistable/deletable_spec.rb +2 -2
- data/spec/mongoid/persistable/destroyable_spec.rb +2 -2
- data/spec/mongoid/persistable/upsertable_spec.rb +14 -0
- data/spec/mongoid/persistence_context_spec.rb +50 -1
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -18
- data/spec/mongoid/query_cache_spec.rb +0 -154
- data/spec/mongoid/reloadable_spec.rb +59 -2
- data/spec/mongoid/scopable_spec.rb +54 -16
- data/spec/mongoid/shardable_models.rb +14 -0
- data/spec/mongoid/shardable_spec.rb +157 -51
- data/spec/mongoid/stateful_spec.rb +28 -0
- data/spec/mongoid/timestamps_spec.rb +390 -0
- data/spec/mongoid/timestamps_spec_models.rb +67 -0
- data/spec/mongoid/touchable_spec.rb +116 -0
- data/spec/mongoid/touchable_spec_models.rb +12 -8
- data/spec/mongoid/traversable_spec.rb +4 -11
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +59 -31
- data/spec/mongoid/warnings_spec.rb +35 -0
- data/spec/mongoid_spec.rb +1 -1
- data/spec/rails/controller_extension/controller_runtime_spec.rb +2 -2
- data/spec/rails/mongoid_spec.rb +4 -16
- data/spec/shared/lib/mrss/docker_runner.rb +7 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/lib/mrss/utils.rb +28 -6
- data/spec/shared/share/Dockerfile.erb +36 -40
- data/spec/shared/shlib/server.sh +32 -8
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/support/constraints.rb +24 -0
- data/spec/support/macros.rb +46 -0
- data/spec/support/models/augmentation.rb +12 -0
- data/spec/support/models/band.rb +3 -0
- data/spec/support/models/catalog.rb +24 -0
- data/spec/support/models/circus.rb +3 -0
- data/spec/support/models/code.rb +2 -0
- data/spec/support/models/fanatic.rb +8 -0
- data/spec/support/models/implant.rb +9 -0
- data/spec/support/models/label.rb +2 -0
- data/spec/support/models/passport.rb +9 -0
- data/spec/support/models/person.rb +2 -0
- data/spec/support/models/player.rb +2 -0
- data/spec/support/models/powerup.rb +12 -0
- data/spec/support/models/purse.rb +9 -0
- data/spec/support/models/registry.rb +1 -0
- data/spec/support/models/school.rb +14 -0
- data/spec/support/models/shield.rb +18 -0
- data/spec/support/models/student.rb +14 -0
- data/spec/support/models/weapon.rb +12 -0
- data.tar.gz.sig +4 -1
- metadata +682 -635
- metadata.gz.sig +0 -0
- data/lib/mongoid/errors/eager_load.rb +0 -23
- data/lib/mongoid/errors/invalid_value.rb +0 -17
- data/spec/mongoid/errors/eager_load_spec.rb +0 -31
@@ -17,6 +17,8 @@ module Mongoid
|
|
17
17
|
include Association::EagerLoadable
|
18
18
|
include Queryable
|
19
19
|
|
20
|
+
Mongoid.deprecate(self, :geo_near)
|
21
|
+
|
20
22
|
# Options constant.
|
21
23
|
OPTIONS = [ :hint,
|
22
24
|
:limit,
|
@@ -35,16 +37,6 @@ module Mongoid
|
|
35
37
|
# @attribute [r] view The Mongo collection view.
|
36
38
|
attr_reader :view
|
37
39
|
|
38
|
-
# Is the context cached?
|
39
|
-
#
|
40
|
-
# @example Is the context cached?
|
41
|
-
# context.cached?
|
42
|
-
#
|
43
|
-
# @return [ true, false ] If the context is cached.
|
44
|
-
def cached?
|
45
|
-
!!@cache
|
46
|
-
end
|
47
|
-
|
48
40
|
# Get the number of documents matching the query.
|
49
41
|
#
|
50
42
|
# @example Get the number of matching documents.
|
@@ -64,7 +56,12 @@ module Mongoid
|
|
64
56
|
# @return [ Integer ] The number of matches.
|
65
57
|
def count(options = {}, &block)
|
66
58
|
return super(&block) if block_given?
|
67
|
-
|
59
|
+
|
60
|
+
if valid_for_count_documents?
|
61
|
+
view.count_documents(options)
|
62
|
+
else
|
63
|
+
view.count(options)
|
64
|
+
end
|
68
65
|
end
|
69
66
|
|
70
67
|
# Get the estimated number of documents matching the query.
|
@@ -83,7 +80,7 @@ module Mongoid
|
|
83
80
|
unless self.criteria.selector.empty?
|
84
81
|
raise Mongoid::Errors::InvalidEstimatedCountCriteria.new(self.klass)
|
85
82
|
end
|
86
|
-
|
83
|
+
view.estimated_document_count(options)
|
87
84
|
end
|
88
85
|
|
89
86
|
# Delete all documents in the database that match the selector.
|
@@ -117,7 +114,7 @@ module Mongoid
|
|
117
114
|
# @example Get the distinct values.
|
118
115
|
# context.distinct(:name)
|
119
116
|
#
|
120
|
-
# @param [ String
|
117
|
+
# @param [ String | Symbol ] field The name of the field.
|
121
118
|
#
|
122
119
|
# @return [ Array<Object> ] The distinct values for the field.
|
123
120
|
def distinct(field)
|
@@ -151,7 +148,6 @@ module Mongoid
|
|
151
148
|
documents_for_iteration.each do |doc|
|
152
149
|
yield_document(doc, &block)
|
153
150
|
end
|
154
|
-
@cache_loaded = true
|
155
151
|
self
|
156
152
|
else
|
157
153
|
to_enum
|
@@ -164,17 +160,11 @@ module Mongoid
|
|
164
160
|
# context.exists?
|
165
161
|
#
|
166
162
|
# @note We don't use count here since Mongo does not use counted
|
167
|
-
# b-tree indexes
|
168
|
-
# used to determine the value.
|
163
|
+
# b-tree indexes.
|
169
164
|
#
|
170
|
-
# @return [ true
|
165
|
+
# @return [ true | false ] If the count is more than zero.
|
171
166
|
def exists?
|
172
|
-
|
173
|
-
return @count > 0 if instance_variable_defined?(:@count)
|
174
|
-
|
175
|
-
try_cache(:exists) do
|
176
|
-
!!(view.projection(_id: 1).limit(1).first)
|
177
|
-
end
|
167
|
+
!!(view.projection(_id: 1).limit(1).first)
|
178
168
|
end
|
179
169
|
|
180
170
|
# Run an explain on the criteria.
|
@@ -196,9 +186,9 @@ module Mongoid
|
|
196
186
|
# @param [ Hash ] update The updates.
|
197
187
|
# @param [ Hash ] options The command options.
|
198
188
|
#
|
199
|
-
# @option options [ :before
|
189
|
+
# @option options [ :before | :after ] :return_document Return the updated document
|
200
190
|
# from before or after update.
|
201
|
-
# @option options [ true
|
191
|
+
# @option options [ true | false ] :upsert Create the document if it doesn't exist.
|
202
192
|
#
|
203
193
|
# @return [ Document ] The result of the command.
|
204
194
|
def find_one_and_update(update, options = {})
|
@@ -216,9 +206,9 @@ module Mongoid
|
|
216
206
|
# @param [ Hash ] replacement The replacement.
|
217
207
|
# @param [ Hash ] options The command options.
|
218
208
|
#
|
219
|
-
# @option options [ :before
|
209
|
+
# @option options [ :before | :after ] :return_document Return the updated document
|
220
210
|
# from before or after update.
|
221
|
-
# @option options [ true
|
211
|
+
# @option options [ true | false ] :upsert Create the document if it doesn't exist.
|
222
212
|
#
|
223
213
|
# @return [ Document ] The result of the command.
|
224
214
|
def find_one_and_replace(replacement, options = {})
|
@@ -248,29 +238,16 @@ module Mongoid
|
|
248
238
|
# @note Automatically adding a sort on _id when no other sort is
|
249
239
|
# defined on the criteria has the potential to cause bad performance issues.
|
250
240
|
# If you experience unexpected poor performance when using #first or #last
|
251
|
-
# and have no sort defined on the criteria, use
|
252
|
-
# Be aware that #
|
253
|
-
#
|
254
|
-
# @param [ Hash ] opts The options for the query returning the first document.
|
241
|
+
# and have no sort defined on the criteria, use #take instead.
|
242
|
+
# Be aware that #take won't guarantee order.
|
255
243
|
#
|
256
|
-
# @
|
257
|
-
# is defined on the criteria.
|
244
|
+
# @param [ Integer ] limit The number of documents to return.
|
258
245
|
#
|
259
246
|
# @return [ Document ] The first document.
|
260
|
-
def first(
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
if raw_doc = view.sort(sort).limit(1).first
|
265
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
266
|
-
eager_load([doc]).first
|
267
|
-
end
|
268
|
-
else
|
269
|
-
if raw_doc = view.limit(1).first
|
270
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
271
|
-
eager_load([doc]).first
|
272
|
-
end
|
273
|
-
end
|
247
|
+
def first(limit = nil)
|
248
|
+
sort = view.sort || { _id: 1 }
|
249
|
+
if raw_docs = view.sort(sort).limit(limit || 1).to_a
|
250
|
+
process_raw_docs(raw_docs, limit)
|
274
251
|
end
|
275
252
|
end
|
276
253
|
alias :one :first
|
@@ -279,7 +256,6 @@ module Mongoid
|
|
279
256
|
#
|
280
257
|
# @api private
|
281
258
|
def find_first
|
282
|
-
return documents.first if cached? && cache_loaded?
|
283
259
|
if raw_doc = view.first
|
284
260
|
doc = Factory.from_db(klass, raw_doc, criteria)
|
285
261
|
eager_load([doc]).first
|
@@ -309,29 +285,6 @@ module Mongoid
|
|
309
285
|
GeoNear.new(collection, criteria, coordinates)
|
310
286
|
end
|
311
287
|
|
312
|
-
# Invoke the block for each element of Contextual. Create a new array
|
313
|
-
# containing the values returned by the block.
|
314
|
-
#
|
315
|
-
# If the symbol field name is passed instead of the block, additional
|
316
|
-
# optimizations would be used.
|
317
|
-
#
|
318
|
-
# @example Map by some field.
|
319
|
-
# context.map(:field1)
|
320
|
-
#
|
321
|
-
# @example Map with block.
|
322
|
-
# context.map(&:field1)
|
323
|
-
#
|
324
|
-
# @param [ Symbol ] field The field name.
|
325
|
-
#
|
326
|
-
# @return [ Array ] The result of mapping.
|
327
|
-
def map(field = nil, &block)
|
328
|
-
if block_given?
|
329
|
-
super(&block)
|
330
|
-
else
|
331
|
-
criteria.pluck(field)
|
332
|
-
end
|
333
|
-
end
|
334
|
-
|
335
288
|
# Create the new Mongo context. This delegates operations to the
|
336
289
|
# underlying driver.
|
337
290
|
#
|
@@ -340,7 +293,7 @@ module Mongoid
|
|
340
293
|
#
|
341
294
|
# @param [ Criteria ] criteria The criteria.
|
342
295
|
def initialize(criteria)
|
343
|
-
@criteria, @klass
|
296
|
+
@criteria, @klass = criteria, criteria.klass
|
344
297
|
@collection = @klass.collection
|
345
298
|
criteria.send(:merge_type_selection)
|
346
299
|
@view = collection.find(criteria.selector, session: _session)
|
@@ -357,32 +310,26 @@ module Mongoid
|
|
357
310
|
# @note Automatically adding a sort on _id when no other sort is
|
358
311
|
# defined on the criteria has the potential to cause bad performance issues.
|
359
312
|
# If you experience unexpected poor performance when using #first or #last
|
360
|
-
# and have no sort defined on the criteria, use
|
361
|
-
# Be aware that #
|
362
|
-
#
|
363
|
-
# @param [
|
364
|
-
#
|
365
|
-
# @
|
366
|
-
|
367
|
-
|
368
|
-
|
369
|
-
with_inverse_sorting(opts) do
|
370
|
-
if raw_doc = view.limit(1).first
|
371
|
-
doc = Factory.from_db(klass, raw_doc, criteria)
|
372
|
-
eager_load([doc]).first
|
373
|
-
end
|
374
|
-
end
|
375
|
-
end
|
313
|
+
# and have no sort defined on the criteria, use #take instead.
|
314
|
+
# Be aware that #take won't guarantee order.
|
315
|
+
#
|
316
|
+
# @param [ Integer ] limit The number of documents to return.
|
317
|
+
#
|
318
|
+
# @return [ Document ] The last document.
|
319
|
+
def last(limit = nil)
|
320
|
+
raw_docs = view.sort(inverse_sorting).limit(limit || 1).to_a.reverse
|
321
|
+
process_raw_docs(raw_docs, limit)
|
376
322
|
end
|
377
323
|
|
378
|
-
#
|
324
|
+
# Returns the number of documents in the database matching
|
325
|
+
# the query selector.
|
379
326
|
#
|
380
327
|
# @example Get the length.
|
381
328
|
# context.length
|
382
329
|
#
|
383
330
|
# @return [ Integer ] The number of documents.
|
384
331
|
def length
|
385
|
-
|
332
|
+
self.count
|
386
333
|
end
|
387
334
|
alias :size :length
|
388
335
|
|
@@ -398,6 +345,44 @@ module Mongoid
|
|
398
345
|
@view = view.limit(value) and self
|
399
346
|
end
|
400
347
|
|
348
|
+
# Take the given number of documents from the database.
|
349
|
+
#
|
350
|
+
# @example Take 10 documents
|
351
|
+
# context.take(10)
|
352
|
+
#
|
353
|
+
# @param [ Integer | nil ] limit The number of documents to return or nil.
|
354
|
+
#
|
355
|
+
# @return [ Document | Array<Document> ] The list of documents, or one
|
356
|
+
# document if no value was given.
|
357
|
+
def take(limit = nil)
|
358
|
+
if limit
|
359
|
+
limit(limit).to_a
|
360
|
+
else
|
361
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
362
|
+
# result is not sorted.
|
363
|
+
limit(1).to_a.first
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
# Take one document from the database and raise an error if there are none.
|
368
|
+
#
|
369
|
+
# @example Take a document
|
370
|
+
# context.take!
|
371
|
+
#
|
372
|
+
# @return [ Document ] The document.
|
373
|
+
#
|
374
|
+
# @raises [ Mongoid::Errors::DocumentNotFound ] raises when there are no
|
375
|
+
# documents to take.
|
376
|
+
def take!
|
377
|
+
# Do to_a first so that the Mongo#first method is not used and the
|
378
|
+
# result is not sorted.
|
379
|
+
if fst = limit(1).to_a.first
|
380
|
+
fst
|
381
|
+
else
|
382
|
+
raise Errors::DocumentNotFound.new(klass, nil, nil)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
401
386
|
# Initiate a map/reduce operation from the context.
|
402
387
|
#
|
403
388
|
# @example Initiate a map/reduce.
|
@@ -417,12 +402,9 @@ module Mongoid
|
|
417
402
|
# @example Pluck a field.
|
418
403
|
# context.pluck(:_id)
|
419
404
|
#
|
420
|
-
# @
|
421
|
-
# serialization.
|
405
|
+
# @param [ String | Symbol ] *fields Field(s) to pluck.
|
422
406
|
#
|
423
|
-
# @
|
424
|
-
#
|
425
|
-
# @return [ Array<Object, Array> ] The plucked values.
|
407
|
+
# @return [ Array<Object> | Array<Array<Object>> ] The plucked values.
|
426
408
|
def pluck(*fields)
|
427
409
|
# Multiple fields can map to the same field name. For example, plucking
|
428
410
|
# a field and its _translations field map to the same field in the database.
|
@@ -452,6 +434,87 @@ module Mongoid
|
|
452
434
|
end
|
453
435
|
end
|
454
436
|
|
437
|
+
# Pick the single field values from the database.
|
438
|
+
#
|
439
|
+
# @example Pick a field.
|
440
|
+
# context.pick(:_id)
|
441
|
+
#
|
442
|
+
# @param [ String | Symbol ] *fields Field(s) to pick.
|
443
|
+
#
|
444
|
+
# @return [ Object | Array<Object> ] The picked values.
|
445
|
+
def pick(*fields)
|
446
|
+
limit(1).pluck(*fields).first
|
447
|
+
end
|
448
|
+
|
449
|
+
# Get a hash of counts for the values of a single field. For example,
|
450
|
+
# if the following documents were in the database:
|
451
|
+
#
|
452
|
+
# { _id: 1, age: 21 }
|
453
|
+
# { _id: 2, age: 21 }
|
454
|
+
# { _id: 3, age: 22 }
|
455
|
+
#
|
456
|
+
# Model.tally("age")
|
457
|
+
#
|
458
|
+
# would yield the following result:
|
459
|
+
#
|
460
|
+
# { 21 => 2, 22 => 1 }
|
461
|
+
#
|
462
|
+
# When tallying a field inside an array or embeds_many association:
|
463
|
+
#
|
464
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 } ] }
|
465
|
+
# { _id: 2, array: [ { x: 1 }, { x: 2 } ] }
|
466
|
+
# { _id: 3, array: [ { x: 1 }, { x: 3 } ] }
|
467
|
+
#
|
468
|
+
# Model.tally("array.x")
|
469
|
+
#
|
470
|
+
# The keys of the resulting hash are arrays:
|
471
|
+
#
|
472
|
+
# { [ 1, 2 ] => 2, [ 1, 3 ] => 1 }
|
473
|
+
#
|
474
|
+
# Note that if tallying an element in an array of hashes, and the key
|
475
|
+
# doesn't exist in some of the hashes, tally will not include those
|
476
|
+
# nil keys in the resulting hash:
|
477
|
+
#
|
478
|
+
# { _id: 1, array: [ { x: 1 }, { x: 2 }, { y: 3 } ] }
|
479
|
+
#
|
480
|
+
# Model.tally("array.x")
|
481
|
+
# # => { [ 1, 2 ] => 1 }
|
482
|
+
#
|
483
|
+
# @param [ String | Symbol ] field The field name.
|
484
|
+
#
|
485
|
+
# @return [ Hash ] The hash of counts.
|
486
|
+
def tally(field)
|
487
|
+
name = klass.cleanse_localized_field_names(field)
|
488
|
+
|
489
|
+
fld = klass.traverse_association_tree(name)
|
490
|
+
pipeline = [ { "$group" => { _id: "$#{name}", counts: { "$sum": 1 } } } ]
|
491
|
+
pipeline.unshift("$match" => view.filter) unless view.filter.blank?
|
492
|
+
|
493
|
+
collection.aggregate(pipeline).reduce({}) do |tallies, doc|
|
494
|
+
is_translation = "#{name}_translations" == field.to_s
|
495
|
+
val = doc["_id"]
|
496
|
+
|
497
|
+
key = if val.is_a?(Array)
|
498
|
+
val.map do |v|
|
499
|
+
demongoize_with_field(fld, v, is_translation)
|
500
|
+
end
|
501
|
+
else
|
502
|
+
demongoize_with_field(fld, val, is_translation)
|
503
|
+
end
|
504
|
+
|
505
|
+
# The only time where a key will already exist in the tallies hash
|
506
|
+
# is when the values are stored differently in the database, but
|
507
|
+
# demongoize to the same value. A good example of when this happens
|
508
|
+
# is when using localized fields. While the server query won't group
|
509
|
+
# together hashes that have other values in different languages, the
|
510
|
+
# demongoized value is just the translation in the current locale,
|
511
|
+
# which can be the same across multiple of those unequal hashes.
|
512
|
+
tallies[key] ||= 0
|
513
|
+
tallies[key] += doc["counts"]
|
514
|
+
tallies
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
455
518
|
# Skips the provided number of documents.
|
456
519
|
#
|
457
520
|
# @example Skip the documents.
|
@@ -518,22 +581,6 @@ module Mongoid
|
|
518
581
|
|
519
582
|
private
|
520
583
|
|
521
|
-
# yield the block given or return the cached value
|
522
|
-
#
|
523
|
-
# @param [ String, Symbol ] key The instance variable name
|
524
|
-
#
|
525
|
-
# @return the result of the block
|
526
|
-
def try_cache(key, &block)
|
527
|
-
unless cached?
|
528
|
-
yield
|
529
|
-
else
|
530
|
-
unless ret = instance_variable_get("@#{key}")
|
531
|
-
instance_variable_set("@#{key}", ret = yield)
|
532
|
-
end
|
533
|
-
ret
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
584
|
# Update the documents for the provided method.
|
538
585
|
#
|
539
586
|
# @api private
|
@@ -544,7 +591,7 @@ module Mongoid
|
|
544
591
|
# @param [ Hash ] attributes The updates.
|
545
592
|
# @param [ Symbol ] method The method to use.
|
546
593
|
#
|
547
|
-
# @return [ true
|
594
|
+
# @return [ true | false ] If the update succeeded.
|
548
595
|
def update_documents(attributes, method = :update_one, opts = {})
|
549
596
|
return false unless attributes
|
550
597
|
attributes = Hash[attributes.map { |k, v| [klass.database_field_name(k.to_s), v] }]
|
@@ -594,55 +641,9 @@ module Mongoid
|
|
594
641
|
# Map the inverse sort symbols to the correct MongoDB values.
|
595
642
|
#
|
596
643
|
# @api private
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
def with_inverse_sorting(opts = {})
|
601
|
-
begin
|
602
|
-
if sort = criteria.options[:sort] || ( { _id: 1 } unless opts[:id_sort] == :none )
|
603
|
-
@view = view.sort(Hash[sort.map{|k, v| [k, -1*v]}])
|
604
|
-
end
|
605
|
-
yield
|
606
|
-
ensure
|
607
|
-
apply_option(:sort)
|
608
|
-
end
|
609
|
-
end
|
610
|
-
|
611
|
-
# Is the cache able to be added to?
|
612
|
-
#
|
613
|
-
# @api private
|
614
|
-
#
|
615
|
-
# @example Is the context cacheable?
|
616
|
-
# context.cacheable?
|
617
|
-
#
|
618
|
-
# @return [ true, false ] If caching, and the cache isn't loaded.
|
619
|
-
def cacheable?
|
620
|
-
cached? && !cache_loaded?
|
621
|
-
end
|
622
|
-
|
623
|
-
# Is the cache fully loaded? Will be true if caching after one full
|
624
|
-
# iteration.
|
625
|
-
#
|
626
|
-
# @api private
|
627
|
-
#
|
628
|
-
# @example Is the cache loaded?
|
629
|
-
# context.cache_loaded?
|
630
|
-
#
|
631
|
-
# @return [ true, false ] If the cache is loaded.
|
632
|
-
def cache_loaded?
|
633
|
-
!!@cache_loaded
|
634
|
-
end
|
635
|
-
|
636
|
-
# Get the documents for cached queries.
|
637
|
-
#
|
638
|
-
# @api private
|
639
|
-
#
|
640
|
-
# @example Get the cached documents.
|
641
|
-
# context.documents
|
642
|
-
#
|
643
|
-
# @return [ Array<Document> ] The documents.
|
644
|
-
def documents
|
645
|
-
@documents ||= []
|
644
|
+
def inverse_sorting
|
645
|
+
sort = view.sort || { _id: 1 }
|
646
|
+
Hash[sort.map{|k, v| [k, -1*v]}]
|
646
647
|
end
|
647
648
|
|
648
649
|
# Get the documents the context should iterate. This follows 3 rules:
|
@@ -658,9 +659,8 @@ module Mongoid
|
|
658
659
|
# @example Get the documents for iteration.
|
659
660
|
# context.documents_for_iteration
|
660
661
|
#
|
661
|
-
# @return [ Array<Document
|
662
|
+
# @return [ Array<Document> | Mongo::Collection::View ] The docs to iterate.
|
662
663
|
def documents_for_iteration
|
663
|
-
return documents if cached? && !documents.empty?
|
664
664
|
return view unless eager_loadable?
|
665
665
|
docs = view.map{ |doc| Factory.from_db(klass, doc, criteria) }
|
666
666
|
eager_load(docs)
|
@@ -680,7 +680,6 @@ module Mongoid
|
|
680
680
|
doc = document.respond_to?(:_id) ?
|
681
681
|
document : Factory.from_db(klass, document, criteria)
|
682
682
|
yield(doc)
|
683
|
-
documents.push(doc) if cacheable?
|
684
683
|
end
|
685
684
|
|
686
685
|
private
|
@@ -693,6 +692,26 @@ module Mongoid
|
|
693
692
|
collection.write_concern.nil? || collection.write_concern.acknowledged?
|
694
693
|
end
|
695
694
|
|
695
|
+
# Fetch the element from the given hash and demongoize it using the
|
696
|
+
# given field. If the obj is an array, map over it and call this method
|
697
|
+
# on all of its elements.
|
698
|
+
#
|
699
|
+
# @param [ Hash | Array<Hash> ] obj The hash or array of hashes to fetch from.
|
700
|
+
# @param [ String ] meth The key to fetch from the hash.
|
701
|
+
# @param [ Field ] field The field to use for demongoization.
|
702
|
+
#
|
703
|
+
# @return [ Object ] The demongoized value.
|
704
|
+
#
|
705
|
+
# @api private
|
706
|
+
def fetch_and_demongoize(obj, meth, field)
|
707
|
+
if obj.is_a?(Array)
|
708
|
+
obj.map { |doc| fetch_and_demongoize(doc, meth, field) }
|
709
|
+
else
|
710
|
+
res = obj.try(:fetch, meth, nil)
|
711
|
+
field ? field.demongoize(res) : res.class.demongoize(res)
|
712
|
+
end
|
713
|
+
end
|
714
|
+
|
696
715
|
# Extracts the value for the given field name from the given attribute
|
697
716
|
# hash.
|
698
717
|
#
|
@@ -701,24 +720,18 @@ module Mongoid
|
|
701
720
|
#
|
702
721
|
# @param [ Object ] The value for the given field name
|
703
722
|
def extract_value(attrs, field_name)
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
field.demongoize(res)
|
708
|
-
else
|
709
|
-
res.class.demongoize(res)
|
710
|
-
end
|
711
|
-
end
|
723
|
+
i = 1
|
724
|
+
num_meths = field_name.count('.') + 1
|
725
|
+
curr = attrs.dup
|
712
726
|
|
713
|
-
|
714
|
-
|
715
|
-
meths.each_with_index.inject(attrs) do |curr, (meth, i)|
|
727
|
+
klass.traverse_association_tree(field_name) do |meth, obj, is_field|
|
728
|
+
field = obj if is_field
|
716
729
|
is_translation = false
|
717
|
-
if
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
730
|
+
# If no association or field was found, check if the meth is an
|
731
|
+
# _translations field.
|
732
|
+
if obj.nil? & tr = meth.match(/(.*)_translations\z/)&.captures&.first
|
733
|
+
is_translation = true
|
734
|
+
meth = tr
|
722
735
|
end
|
723
736
|
|
724
737
|
# 1. If curr is an array fetch from all elements in the array.
|
@@ -731,31 +744,24 @@ module Mongoid
|
|
731
744
|
# 3. If the meth is an _translations field, do not demongoize the
|
732
745
|
# value so the full hash is returned.
|
733
746
|
# 4. Otherwise, fetch and demongoize the value for the key meth.
|
734
|
-
if curr.is_a? Array
|
735
|
-
res =
|
747
|
+
curr = if curr.is_a? Array
|
748
|
+
res = fetch_and_demongoize(curr, meth, field)
|
736
749
|
res.empty? ? nil : res
|
737
|
-
elsif !is_translation &&
|
738
|
-
if i <
|
750
|
+
elsif !is_translation && field&.localized?
|
751
|
+
if i < num_meths
|
739
752
|
curr.try(:fetch, meth, nil)
|
740
753
|
else
|
741
|
-
fetch_and_demongoize(curr, meth,
|
754
|
+
fetch_and_demongoize(curr, meth, field)
|
742
755
|
end
|
743
756
|
elsif is_translation
|
744
757
|
curr.try(:fetch, meth, nil)
|
745
758
|
else
|
746
|
-
fetch_and_demongoize(curr, meth,
|
747
|
-
end.tap do
|
748
|
-
if as = k.try(:aliased_associations)
|
749
|
-
if a = as.fetch(meth, nil)
|
750
|
-
meth = a
|
751
|
-
end
|
752
|
-
end
|
753
|
-
|
754
|
-
if relation = k.relations[meth]
|
755
|
-
k = relation.klass
|
756
|
-
end
|
759
|
+
fetch_and_demongoize(curr, meth, field)
|
757
760
|
end
|
761
|
+
|
762
|
+
i += 1
|
758
763
|
end
|
764
|
+
curr
|
759
765
|
end
|
760
766
|
|
761
767
|
# Recursively demongoize the given value. This method recursively traverses
|
@@ -763,35 +769,72 @@ module Mongoid
|
|
763
769
|
#
|
764
770
|
# @param [ String ] field_name The name of the field to demongoize.
|
765
771
|
# @param [ Object ] value The value to demongoize.
|
766
|
-
# @param [
|
772
|
+
# @param [ true | false ] is_translation The field we are retrieving is an
|
767
773
|
# _translations field.
|
768
774
|
#
|
769
775
|
# @return [ Object ] The demongoized value.
|
770
776
|
def recursive_demongoize(field_name, value, is_translation)
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
if a = as.fetch(meth, nil)
|
775
|
-
meth = a.to_s
|
776
|
-
end
|
777
|
-
end
|
777
|
+
field = klass.traverse_association_tree(field_name)
|
778
|
+
demongoize_with_field(field, value, is_translation)
|
779
|
+
end
|
778
780
|
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
783
|
-
|
784
|
-
|
785
|
-
|
786
|
-
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
781
|
+
# Demongoize the value for the given field. If the field is nil or the
|
782
|
+
# field is a translations field, the value is demongoized using its class.
|
783
|
+
#
|
784
|
+
# @param [ Field ] field The field to use to demongoize.
|
785
|
+
# @param [ Object ] value The value to demongoize.
|
786
|
+
# @param [ true | false ] is_translation The field we are retrieving is an
|
787
|
+
# _translations field.
|
788
|
+
#
|
789
|
+
# @return [ Object ] The demongoized value.
|
790
|
+
#
|
791
|
+
# @api private
|
792
|
+
def demongoize_with_field(field, value, is_translation)
|
793
|
+
if field
|
794
|
+
# If it's a localized field that's not a hash, don't demongoize
|
795
|
+
# again, we already have the translation. If it's an _translations
|
796
|
+
# field, don't demongoize, we want the full hash not just a
|
797
|
+
# specific translation.
|
798
|
+
# If it is a hash, and it's not a translations field, we need to
|
799
|
+
# demongoize to get the correct translation.
|
800
|
+
if field.localized? && (!value.is_a?(Hash) || is_translation)
|
801
|
+
value.class.demongoize(value)
|
791
802
|
else
|
792
|
-
|
803
|
+
field.demongoize(value)
|
793
804
|
end
|
805
|
+
else
|
806
|
+
value.class.demongoize(value)
|
807
|
+
end
|
808
|
+
end
|
809
|
+
|
810
|
+
# Process the raw documents retrieved for #first/#last.
|
811
|
+
#
|
812
|
+
# @return [ Array<Document> | Document ] The list of documents or a
|
813
|
+
# single document.
|
814
|
+
def process_raw_docs(raw_docs, limit)
|
815
|
+
docs = raw_docs.map do |d|
|
816
|
+
Factory.from_db(klass, d, criteria)
|
794
817
|
end
|
818
|
+
docs = eager_load(docs)
|
819
|
+
limit ? docs : docs.first
|
820
|
+
end
|
821
|
+
|
822
|
+
# Queries whether the current context is valid for use with
|
823
|
+
# the #count_documents? predicate. A context is valid if it
|
824
|
+
# does not include a `$where` operator.
|
825
|
+
#
|
826
|
+
# @return [ true | false ] whether or not the current context
|
827
|
+
# excludes a `$where` operator.
|
828
|
+
def valid_for_count_documents?(hash = view.filter)
|
829
|
+
# Note that `view.filter` is a BSON::Document, and all keys in a
|
830
|
+
# BSON::Document are strings; we don't need to worry about symbol
|
831
|
+
# representations of `$where`.
|
832
|
+
hash.keys.each do |key|
|
833
|
+
return false if key == '$where'
|
834
|
+
return false if hash[key].is_a?(Hash) && !valid_for_count_documents?(hash[key])
|
835
|
+
end
|
836
|
+
|
837
|
+
true
|
795
838
|
end
|
796
839
|
end
|
797
840
|
end
|