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
@@ -0,0 +1,1492 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require_relative "./includable_spec_models.rb"
|
5
|
+
|
6
|
+
describe Mongoid::Criteria::Includable do
|
7
|
+
|
8
|
+
describe "#includes" do
|
9
|
+
|
10
|
+
let!(:person) do
|
11
|
+
Person.create!(age: 1)
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when providing a name that is not a relation" do
|
15
|
+
|
16
|
+
it "raises an error" do
|
17
|
+
expect {
|
18
|
+
Person.includes(:members)
|
19
|
+
}.to raise_error(Mongoid::Errors::InvalidIncludes)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when providing one association" do
|
24
|
+
|
25
|
+
let!(:user) do
|
26
|
+
User.create!(posts: [ post1 ])
|
27
|
+
end
|
28
|
+
|
29
|
+
let!(:post1) do
|
30
|
+
Post.create!
|
31
|
+
end
|
32
|
+
|
33
|
+
let(:result) do
|
34
|
+
User.includes(:posts).first
|
35
|
+
end
|
36
|
+
|
37
|
+
it "executes the query" do
|
38
|
+
expect(result).to eq(user)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "includes the related objects" do
|
42
|
+
expect(result.posts).to eq([ post1 ])
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when providing a list of associations" do
|
47
|
+
|
48
|
+
let!(:user) do
|
49
|
+
User.create!(posts: [ post1 ], descriptions: [ description1 ])
|
50
|
+
end
|
51
|
+
|
52
|
+
let!(:post1) do
|
53
|
+
Post.create!
|
54
|
+
end
|
55
|
+
|
56
|
+
let!(:description1) do
|
57
|
+
Description.create!(details: 1)
|
58
|
+
end
|
59
|
+
|
60
|
+
let(:result) do
|
61
|
+
User.includes(:posts, :descriptions).first
|
62
|
+
end
|
63
|
+
|
64
|
+
it "executes the query" do
|
65
|
+
expect(result).to eq(user)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "includes the related objects" do
|
69
|
+
expect(result.posts).to eq([ post1 ])
|
70
|
+
expect(result.descriptions).to eq([ description1 ])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when providing a nested association" do
|
75
|
+
|
76
|
+
let!(:user) do
|
77
|
+
User.create!
|
78
|
+
end
|
79
|
+
|
80
|
+
before do
|
81
|
+
p = Post.create!(alerts: [ Alert.create! ])
|
82
|
+
user.posts = [ p ]
|
83
|
+
user.save!
|
84
|
+
end
|
85
|
+
|
86
|
+
let(:result) do
|
87
|
+
User.includes(:posts => [:alerts]).first
|
88
|
+
end
|
89
|
+
|
90
|
+
it "executes the query" do
|
91
|
+
expect(result).to eq(user)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "includes the related objects" do
|
95
|
+
expect(result.posts.size).to eq(1)
|
96
|
+
expect(result.posts.first.alerts.size).to eq(1)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "when providing a deeply nested association" do
|
101
|
+
|
102
|
+
let!(:user) do
|
103
|
+
User.create!
|
104
|
+
end
|
105
|
+
|
106
|
+
let(:results) do
|
107
|
+
User.includes(:posts => [{ :alerts => :items }]).to_a
|
108
|
+
end
|
109
|
+
|
110
|
+
it "executes the query" do
|
111
|
+
expect(results.first).to eq(user)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
context "when the models are inherited" do
|
116
|
+
|
117
|
+
before(:all) do
|
118
|
+
class A
|
119
|
+
include Mongoid::Document
|
120
|
+
end
|
121
|
+
|
122
|
+
class B < A
|
123
|
+
belongs_to :c
|
124
|
+
end
|
125
|
+
|
126
|
+
class C
|
127
|
+
include Mongoid::Document
|
128
|
+
has_one :b
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
after(:all) do
|
133
|
+
Object.send(:remove_const, :A)
|
134
|
+
Object.send(:remove_const, :B)
|
135
|
+
Object.send(:remove_const, :C)
|
136
|
+
end
|
137
|
+
|
138
|
+
context "when the includes is on the subclass" do
|
139
|
+
|
140
|
+
let!(:c_one) do
|
141
|
+
C.create!
|
142
|
+
end
|
143
|
+
|
144
|
+
let!(:c_two) do
|
145
|
+
C.create!
|
146
|
+
end
|
147
|
+
|
148
|
+
let!(:b) do
|
149
|
+
B.create!(c: c_two)
|
150
|
+
end
|
151
|
+
|
152
|
+
let!(:results) do
|
153
|
+
C.includes(:b).to_a.detect do |c|
|
154
|
+
c.id == c_two.id
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
it "returns the correct documents" do
|
159
|
+
expect(results).to eq(c_two)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "does not query the db" do
|
163
|
+
expect_query(0) do
|
164
|
+
results.b
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
context "when the models are inherited from another one model" do
|
171
|
+
|
172
|
+
context "when the relation is a has_one" do
|
173
|
+
|
174
|
+
before(:all) do
|
175
|
+
class A
|
176
|
+
include Mongoid::Document
|
177
|
+
end
|
178
|
+
|
179
|
+
class B < A
|
180
|
+
belongs_to :d
|
181
|
+
end
|
182
|
+
|
183
|
+
class C < A
|
184
|
+
belongs_to :d
|
185
|
+
end
|
186
|
+
|
187
|
+
class D
|
188
|
+
include Mongoid::Document
|
189
|
+
has_one :b
|
190
|
+
has_one :c
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
after(:all) do
|
195
|
+
Object.send(:remove_const, :A)
|
196
|
+
Object.send(:remove_const, :B)
|
197
|
+
Object.send(:remove_const, :C)
|
198
|
+
Object.send(:remove_const, :D)
|
199
|
+
end
|
200
|
+
|
201
|
+
context "when the includes is on the several relations" do
|
202
|
+
|
203
|
+
let!(:d_one) do
|
204
|
+
D.create!
|
205
|
+
end
|
206
|
+
|
207
|
+
let!(:d_two) do
|
208
|
+
D.create!
|
209
|
+
end
|
210
|
+
|
211
|
+
let!(:b) do
|
212
|
+
B.create!(d: d_two)
|
213
|
+
end
|
214
|
+
|
215
|
+
let!(:c) do
|
216
|
+
C.create!(d: d_two)
|
217
|
+
end
|
218
|
+
|
219
|
+
let!(:results) do
|
220
|
+
D.includes(:b, :c).entries.detect do |d|
|
221
|
+
d.id == d_two.id
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
it "returns the correct documents" do
|
226
|
+
expect(results).to eq(d_two)
|
227
|
+
end
|
228
|
+
|
229
|
+
it "does not query the db on b" do
|
230
|
+
expect_query(0) do
|
231
|
+
results.b
|
232
|
+
end
|
233
|
+
end
|
234
|
+
|
235
|
+
it "does not query the db on c" do
|
236
|
+
expect_query(0) do
|
237
|
+
results.b
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
context "when the relation is a has_many" do
|
244
|
+
|
245
|
+
before(:all) do
|
246
|
+
class A
|
247
|
+
include Mongoid::Document
|
248
|
+
end
|
249
|
+
|
250
|
+
class B < A
|
251
|
+
belongs_to :d
|
252
|
+
end
|
253
|
+
|
254
|
+
class C < A
|
255
|
+
belongs_to :d
|
256
|
+
end
|
257
|
+
|
258
|
+
class D
|
259
|
+
include Mongoid::Document
|
260
|
+
has_many :b
|
261
|
+
has_many :c
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
after(:all) do
|
266
|
+
Object.send(:remove_const, :A)
|
267
|
+
Object.send(:remove_const, :B)
|
268
|
+
Object.send(:remove_const, :C)
|
269
|
+
Object.send(:remove_const, :D)
|
270
|
+
end
|
271
|
+
|
272
|
+
context "when the includes is on the several relations" do
|
273
|
+
|
274
|
+
let!(:d_one) do
|
275
|
+
D.create!
|
276
|
+
end
|
277
|
+
|
278
|
+
let!(:d_two) do
|
279
|
+
D.create!
|
280
|
+
end
|
281
|
+
|
282
|
+
let!(:bs) do
|
283
|
+
2.times.map { B.create!(d: d_two) }
|
284
|
+
end
|
285
|
+
|
286
|
+
let!(:cs) do
|
287
|
+
2.times.map { C.create!(d: d_two) }
|
288
|
+
end
|
289
|
+
|
290
|
+
let!(:results) do
|
291
|
+
D.includes(:b, :c).entries.detect do |d|
|
292
|
+
d.id == d_two.id
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
it "returns the correct documents" do
|
297
|
+
expect(results).to eq(d_two)
|
298
|
+
end
|
299
|
+
|
300
|
+
it "does not query the db on b" do
|
301
|
+
expect_query(0) do
|
302
|
+
results.b
|
303
|
+
end
|
304
|
+
end
|
305
|
+
|
306
|
+
it "does not query the db on c" do
|
307
|
+
expect_query(0) do
|
308
|
+
results.b
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
context "when including the same association multiple times" do
|
316
|
+
|
317
|
+
let(:criteria) do
|
318
|
+
Person.all.includes(:posts, :posts).includes(:posts)
|
319
|
+
end
|
320
|
+
|
321
|
+
let(:association) do
|
322
|
+
Person.reflect_on_association(:posts)
|
323
|
+
end
|
324
|
+
|
325
|
+
it "does not duplicate the association in the inclusions" do
|
326
|
+
expect(criteria.inclusions).to eq([ association ])
|
327
|
+
end
|
328
|
+
end
|
329
|
+
|
330
|
+
context "when mapping the results more than once" do
|
331
|
+
|
332
|
+
let!(:post) do
|
333
|
+
person.posts.create!(title: "one")
|
334
|
+
end
|
335
|
+
|
336
|
+
let(:criteria) do
|
337
|
+
Post.includes(:person)
|
338
|
+
end
|
339
|
+
|
340
|
+
let!(:results) do
|
341
|
+
criteria.map { |doc| doc }
|
342
|
+
criteria.map { |doc| doc }
|
343
|
+
end
|
344
|
+
|
345
|
+
it "returns the proper results" do
|
346
|
+
expect(results.first.title).to eq("one")
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context "when including a belongs to relation" do
|
351
|
+
|
352
|
+
context "when the criteria is from the root" do
|
353
|
+
|
354
|
+
let!(:person_two) do
|
355
|
+
Person.create!(age: 2)
|
356
|
+
end
|
357
|
+
|
358
|
+
let!(:post_one) do
|
359
|
+
person.posts.create!(title: "one")
|
360
|
+
end
|
361
|
+
|
362
|
+
let!(:post_two) do
|
363
|
+
person_two.posts.create!(title: "two")
|
364
|
+
end
|
365
|
+
|
366
|
+
context "when calling first" do
|
367
|
+
|
368
|
+
let(:criteria) do
|
369
|
+
Post.includes(:person)
|
370
|
+
end
|
371
|
+
|
372
|
+
let!(:document) do
|
373
|
+
criteria.first
|
374
|
+
end
|
375
|
+
|
376
|
+
it "eager loads the first document" do
|
377
|
+
expect_query(0) do
|
378
|
+
expect(document.person).to eq(person)
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
it "returns the first document" do
|
383
|
+
expect(document).to eq(post_one)
|
384
|
+
end
|
385
|
+
end
|
386
|
+
|
387
|
+
context "when calling last" do
|
388
|
+
|
389
|
+
let!(:criteria) do
|
390
|
+
Post.asc(:_id).includes(:person)
|
391
|
+
end
|
392
|
+
|
393
|
+
let!(:document) do
|
394
|
+
criteria.last
|
395
|
+
end
|
396
|
+
|
397
|
+
it "eager loads the last document" do
|
398
|
+
expect_query(0) do
|
399
|
+
expect(document.person).to eq(person_two)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
it "returns the last document" do
|
404
|
+
expect(document).to eq(post_two)
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
context "when the criteria is from an embedded relation" do
|
410
|
+
|
411
|
+
let(:peep) do
|
412
|
+
Person.create!
|
413
|
+
end
|
414
|
+
|
415
|
+
let!(:address_one) do
|
416
|
+
peep.addresses.create!(street: "rosenthaler")
|
417
|
+
end
|
418
|
+
|
419
|
+
let!(:address_two) do
|
420
|
+
peep.addresses.create!(street: "weinmeister")
|
421
|
+
end
|
422
|
+
|
423
|
+
let!(:depeche) do
|
424
|
+
Band.create!(name: "Depeche Mode")
|
425
|
+
end
|
426
|
+
|
427
|
+
let!(:tool) do
|
428
|
+
Band.create!(name: "Tool")
|
429
|
+
end
|
430
|
+
|
431
|
+
before do
|
432
|
+
address_one.band = depeche
|
433
|
+
address_two.band = tool
|
434
|
+
address_one.save!
|
435
|
+
address_two.save!
|
436
|
+
end
|
437
|
+
|
438
|
+
context "when calling first" do
|
439
|
+
|
440
|
+
let(:criteria) do
|
441
|
+
peep.reload.addresses.includes(:band)
|
442
|
+
end
|
443
|
+
|
444
|
+
let(:context) do
|
445
|
+
criteria.context
|
446
|
+
end
|
447
|
+
|
448
|
+
let!(:document) do
|
449
|
+
criteria.first
|
450
|
+
end
|
451
|
+
|
452
|
+
it "eager loads the first document" do
|
453
|
+
expect_query(0) do
|
454
|
+
expect(document.band).to eq(depeche)
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
it "returns the document" do
|
459
|
+
expect(document).to eq(address_one)
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
context "when calling last" do
|
464
|
+
|
465
|
+
let(:criteria) do
|
466
|
+
peep.reload.addresses.includes(:band)
|
467
|
+
end
|
468
|
+
|
469
|
+
let(:context) do
|
470
|
+
criteria.context
|
471
|
+
end
|
472
|
+
|
473
|
+
let!(:document) do
|
474
|
+
criteria.last
|
475
|
+
end
|
476
|
+
|
477
|
+
it "eager loads the last document" do
|
478
|
+
expect_query(0) do
|
479
|
+
expect(document.band).to eq(tool)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
it "returns the document" do
|
484
|
+
expect(document).to eq(address_two)
|
485
|
+
end
|
486
|
+
end
|
487
|
+
|
488
|
+
context "when iterating all documents" do
|
489
|
+
|
490
|
+
let(:criteria) do
|
491
|
+
peep.reload.addresses.includes(:band)
|
492
|
+
end
|
493
|
+
|
494
|
+
let(:context) do
|
495
|
+
criteria.context
|
496
|
+
end
|
497
|
+
|
498
|
+
let!(:documents) do
|
499
|
+
criteria.to_a
|
500
|
+
end
|
501
|
+
|
502
|
+
it "eager loads the first document" do
|
503
|
+
expect_query(0) do
|
504
|
+
expect(documents.first.band).to eq(depeche)
|
505
|
+
end
|
506
|
+
end
|
507
|
+
|
508
|
+
it "eager loads the last document" do
|
509
|
+
expect_query(0) do
|
510
|
+
expect(documents.last.band).to eq(tool)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
it "returns the documents" do
|
515
|
+
expect(documents).to eq([ address_one, address_two ])
|
516
|
+
end
|
517
|
+
end
|
518
|
+
end
|
519
|
+
end
|
520
|
+
|
521
|
+
context "when providing inclusions to the default scope" do
|
522
|
+
|
523
|
+
before do
|
524
|
+
Person.default_scope(->{ Person.includes(:posts) })
|
525
|
+
end
|
526
|
+
|
527
|
+
after do
|
528
|
+
Person.default_scoping = nil
|
529
|
+
end
|
530
|
+
|
531
|
+
let!(:post_one) do
|
532
|
+
person.posts.create!(title: "one")
|
533
|
+
end
|
534
|
+
|
535
|
+
let!(:post_two) do
|
536
|
+
person.posts.create!(title: "two")
|
537
|
+
end
|
538
|
+
|
539
|
+
context "when the criteria has no options" do
|
540
|
+
|
541
|
+
let!(:criteria) do
|
542
|
+
Person.asc(:age).all
|
543
|
+
end
|
544
|
+
|
545
|
+
let!(:documents) do
|
546
|
+
criteria.entries
|
547
|
+
end
|
548
|
+
|
549
|
+
it "returns the correct documents" do
|
550
|
+
expect(documents).to eq([ person ])
|
551
|
+
end
|
552
|
+
|
553
|
+
it "eager loads the first document" do
|
554
|
+
expect_query(0) do
|
555
|
+
expect(documents.first.posts.first).to eq(post_one)
|
556
|
+
end
|
557
|
+
end
|
558
|
+
|
559
|
+
it "eager loads the last document" do
|
560
|
+
expect_query(0) do
|
561
|
+
expect(documents.first.posts.last).to eq(post_two)
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
context "when executing the query twice" do
|
566
|
+
|
567
|
+
let!(:new_criteria) do
|
568
|
+
Person.where(id: person.id)
|
569
|
+
end
|
570
|
+
|
571
|
+
let!(:new_context) do
|
572
|
+
new_criteria.context
|
573
|
+
end
|
574
|
+
|
575
|
+
before do
|
576
|
+
expect(new_context).to receive(:eager_load).with([person]).once.and_call_original
|
577
|
+
end
|
578
|
+
|
579
|
+
let!(:from_db) do
|
580
|
+
new_criteria.first
|
581
|
+
end
|
582
|
+
|
583
|
+
it "does not duplicate documents in the relation" do
|
584
|
+
expect(person.posts.size).to eq(2)
|
585
|
+
end
|
586
|
+
end
|
587
|
+
end
|
588
|
+
|
589
|
+
context "when calling first on the criteria" do
|
590
|
+
|
591
|
+
let(:criteria) do
|
592
|
+
Person.asc(:age).all
|
593
|
+
end
|
594
|
+
|
595
|
+
let!(:from_db) do
|
596
|
+
criteria.first
|
597
|
+
end
|
598
|
+
|
599
|
+
it "returns the correct documents" do
|
600
|
+
expect(from_db).to eq(person)
|
601
|
+
end
|
602
|
+
|
603
|
+
it "eager loads the first document" do
|
604
|
+
expect_query(0) do
|
605
|
+
expect(from_db.posts.first).to eq(post_one)
|
606
|
+
end
|
607
|
+
end
|
608
|
+
|
609
|
+
it "eager loads the last document" do
|
610
|
+
expect_query(0) do
|
611
|
+
expect(from_db.posts.last).to eq(post_two)
|
612
|
+
end
|
613
|
+
end
|
614
|
+
end
|
615
|
+
|
616
|
+
context "when calling last on the criteria" do
|
617
|
+
|
618
|
+
let(:criteria) do
|
619
|
+
Person.asc(:age).all
|
620
|
+
end
|
621
|
+
|
622
|
+
let!(:context) do
|
623
|
+
criteria.context
|
624
|
+
end
|
625
|
+
|
626
|
+
before do
|
627
|
+
expect(context).to receive(:eager_load).with([person]).once.and_call_original
|
628
|
+
end
|
629
|
+
|
630
|
+
let!(:from_db) do
|
631
|
+
criteria.last
|
632
|
+
end
|
633
|
+
|
634
|
+
it "returns the correct documents" do
|
635
|
+
expect(from_db).to eq(person)
|
636
|
+
end
|
637
|
+
|
638
|
+
it "eager loads the first document" do
|
639
|
+
expect_query(0) do
|
640
|
+
expect(from_db.posts.first).to eq(post_one)
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
it "eager loads the last document" do
|
645
|
+
expect_query(0) do
|
646
|
+
expect(from_db.posts.last).to eq(post_two)
|
647
|
+
end
|
648
|
+
end
|
649
|
+
end
|
650
|
+
|
651
|
+
context "when the criteria has limiting options" do
|
652
|
+
|
653
|
+
let!(:person_two) do
|
654
|
+
Person.create!
|
655
|
+
end
|
656
|
+
|
657
|
+
let!(:post_three) do
|
658
|
+
person_two.posts.create!(title: "three")
|
659
|
+
end
|
660
|
+
|
661
|
+
let!(:criteria) do
|
662
|
+
Person.asc(:age).limit(1)
|
663
|
+
end
|
664
|
+
|
665
|
+
let!(:documents) do
|
666
|
+
criteria.entries
|
667
|
+
end
|
668
|
+
|
669
|
+
it "returns the correct documents" do
|
670
|
+
expect(criteria).to eq([ person ])
|
671
|
+
end
|
672
|
+
|
673
|
+
it "eager loads the first document" do
|
674
|
+
expect_query(0) do
|
675
|
+
expect(documents.first.posts.first).to eq(post_one)
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
it "eager loads the second document" do
|
680
|
+
expect_query(0) do
|
681
|
+
expect(documents.first.posts.last).to eq(post_two)
|
682
|
+
end
|
683
|
+
end
|
684
|
+
end
|
685
|
+
end
|
686
|
+
|
687
|
+
context "when including a has and belongs to many" do
|
688
|
+
|
689
|
+
let!(:preference_one) do
|
690
|
+
person.preferences.create!(name: "one")
|
691
|
+
end
|
692
|
+
|
693
|
+
let!(:preference_two) do
|
694
|
+
person.preferences.create!(name: "two")
|
695
|
+
end
|
696
|
+
|
697
|
+
context "when one of the related items is deleted" do
|
698
|
+
|
699
|
+
before do
|
700
|
+
person.preferences = [ preference_one, preference_two ]
|
701
|
+
preference_two.delete
|
702
|
+
end
|
703
|
+
|
704
|
+
let(:criteria) do
|
705
|
+
Person.where(id: person.id).includes(:preferences)
|
706
|
+
end
|
707
|
+
|
708
|
+
it "only loads the existing related items" do
|
709
|
+
expect(criteria.entries.first.preferences).to eq([ preference_one ])
|
710
|
+
end
|
711
|
+
end
|
712
|
+
|
713
|
+
context "when the criteria has no options" do
|
714
|
+
|
715
|
+
let!(:criteria) do
|
716
|
+
Person.asc(:age).includes(:preferences)
|
717
|
+
end
|
718
|
+
|
719
|
+
let!(:documents) do
|
720
|
+
criteria.entries
|
721
|
+
end
|
722
|
+
|
723
|
+
it "returns the correct documents" do
|
724
|
+
expect(documents).to eq([ person ])
|
725
|
+
end
|
726
|
+
|
727
|
+
it "eager loads the first document" do
|
728
|
+
expect_query(0) do
|
729
|
+
expect(documents.first.preferences.first).to eq(preference_one)
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
it "eager loads the last document" do
|
734
|
+
expect_query(0) do
|
735
|
+
expect(documents.first.preferences.last).to eq(preference_two)
|
736
|
+
end
|
737
|
+
end
|
738
|
+
end
|
739
|
+
|
740
|
+
context "when calling first on the criteria" do
|
741
|
+
|
742
|
+
let!(:criteria) do
|
743
|
+
Person.asc(:age).includes(:preferences)
|
744
|
+
end
|
745
|
+
|
746
|
+
let!(:from_db) do
|
747
|
+
criteria.first
|
748
|
+
end
|
749
|
+
|
750
|
+
it "returns the correct documents" do
|
751
|
+
expect(from_db).to eq(person)
|
752
|
+
end
|
753
|
+
|
754
|
+
it "eager loads the first document" do
|
755
|
+
expect_query(0) do
|
756
|
+
expect(from_db.preferences.first).to eq(preference_one)
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
it "eager loads the last document" do
|
761
|
+
expect_query(0) do
|
762
|
+
expect(from_db.preferences.last).to eq(preference_two)
|
763
|
+
end
|
764
|
+
end
|
765
|
+
end
|
766
|
+
|
767
|
+
context "when calling last on the criteria" do
|
768
|
+
|
769
|
+
let!(:criteria) do
|
770
|
+
Person.asc(:age).includes(:preferences)
|
771
|
+
end
|
772
|
+
|
773
|
+
let!(:from_db) do
|
774
|
+
criteria.last
|
775
|
+
end
|
776
|
+
|
777
|
+
it "returns the correct documents" do
|
778
|
+
expect(from_db).to eq(person)
|
779
|
+
end
|
780
|
+
|
781
|
+
it "eager loads the first document" do
|
782
|
+
expect_query(0) do
|
783
|
+
expect(from_db.preferences.first).to eq(preference_one)
|
784
|
+
end
|
785
|
+
end
|
786
|
+
|
787
|
+
it "eager loads the last document" do
|
788
|
+
expect_query(0) do
|
789
|
+
expect(from_db.preferences.last).to eq(preference_two)
|
790
|
+
end
|
791
|
+
end
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
context "when including a has many" do
|
796
|
+
|
797
|
+
let!(:post_one) do
|
798
|
+
person.posts.create!(title: "one")
|
799
|
+
end
|
800
|
+
|
801
|
+
let!(:post_two) do
|
802
|
+
person.posts.create!(title: "two")
|
803
|
+
end
|
804
|
+
|
805
|
+
context "when the criteria has no options" do
|
806
|
+
|
807
|
+
let!(:criteria) do
|
808
|
+
Person.asc(:age).includes(:posts)
|
809
|
+
end
|
810
|
+
|
811
|
+
let!(:documents) do
|
812
|
+
criteria.entries
|
813
|
+
end
|
814
|
+
|
815
|
+
it "returns the correct documents" do
|
816
|
+
expect(documents).to eq([ person ])
|
817
|
+
end
|
818
|
+
|
819
|
+
it "eager loads the first document" do
|
820
|
+
expect_query(0) do
|
821
|
+
expect(documents.first.posts.first).to eq(post_one)
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
it "eager loads the last document" do
|
826
|
+
expect_query(0) do
|
827
|
+
expect(documents.first.posts.last).to eq(post_two)
|
828
|
+
end
|
829
|
+
end
|
830
|
+
end
|
831
|
+
|
832
|
+
context "when calling first on the criteria" do
|
833
|
+
|
834
|
+
let!(:criteria) do
|
835
|
+
Person.asc(:age).includes(:posts)
|
836
|
+
end
|
837
|
+
|
838
|
+
let!(:from_db) do
|
839
|
+
criteria.first
|
840
|
+
end
|
841
|
+
|
842
|
+
it "returns the correct documents" do
|
843
|
+
expect(from_db).to eq(person)
|
844
|
+
end
|
845
|
+
|
846
|
+
context "when subsequently getting all documents" do
|
847
|
+
|
848
|
+
let!(:documents) do
|
849
|
+
criteria.entries
|
850
|
+
end
|
851
|
+
|
852
|
+
it "returns the correct documents" do
|
853
|
+
expect(documents).to eq([ person ])
|
854
|
+
end
|
855
|
+
end
|
856
|
+
end
|
857
|
+
|
858
|
+
context "when calling last on the criteria" do
|
859
|
+
|
860
|
+
let!(:criteria) do
|
861
|
+
Person.asc(:age).includes(:posts)
|
862
|
+
end
|
863
|
+
|
864
|
+
let!(:from_db) do
|
865
|
+
criteria.last
|
866
|
+
end
|
867
|
+
|
868
|
+
it "returns the correct documents" do
|
869
|
+
expect(from_db).to eq(person)
|
870
|
+
end
|
871
|
+
|
872
|
+
context "when subsequently getting all documents" do
|
873
|
+
|
874
|
+
let!(:documents) do
|
875
|
+
criteria.entries
|
876
|
+
end
|
877
|
+
|
878
|
+
it "returns the correct documents" do
|
879
|
+
expect(documents).to eq([ person ])
|
880
|
+
end
|
881
|
+
end
|
882
|
+
end
|
883
|
+
|
884
|
+
context "when the criteria has limiting options" do
|
885
|
+
|
886
|
+
let!(:person_two) do
|
887
|
+
Person.create!
|
888
|
+
end
|
889
|
+
|
890
|
+
let!(:post_three) do
|
891
|
+
person_two.posts.create!(title: "three")
|
892
|
+
end
|
893
|
+
|
894
|
+
let!(:criteria) do
|
895
|
+
Person.includes(:posts).asc(:age).limit(1)
|
896
|
+
end
|
897
|
+
|
898
|
+
let(:context) do
|
899
|
+
criteria.context
|
900
|
+
end
|
901
|
+
|
902
|
+
before do
|
903
|
+
expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
|
904
|
+
end
|
905
|
+
|
906
|
+
let!(:documents) do
|
907
|
+
criteria.entries
|
908
|
+
end
|
909
|
+
|
910
|
+
it "returns the correct documents" do
|
911
|
+
expect(documents).to eq([ person ])
|
912
|
+
end
|
913
|
+
end
|
914
|
+
end
|
915
|
+
|
916
|
+
context "when including a has one" do
|
917
|
+
|
918
|
+
let!(:game_one) do
|
919
|
+
person.create_game(name: "one")
|
920
|
+
end
|
921
|
+
|
922
|
+
let!(:game_two) do
|
923
|
+
person.create_game(name: "two")
|
924
|
+
end
|
925
|
+
|
926
|
+
context "when the criteria has no options" do
|
927
|
+
|
928
|
+
let!(:criteria) do
|
929
|
+
Person.asc(:age).includes(:game)
|
930
|
+
end
|
931
|
+
|
932
|
+
let(:context) do
|
933
|
+
criteria.context
|
934
|
+
end
|
935
|
+
|
936
|
+
before do
|
937
|
+
expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
|
938
|
+
end
|
939
|
+
|
940
|
+
let!(:documents) do
|
941
|
+
criteria.entries
|
942
|
+
end
|
943
|
+
|
944
|
+
it "returns the correct documents" do
|
945
|
+
expect(documents).to eq([ person ])
|
946
|
+
end
|
947
|
+
end
|
948
|
+
|
949
|
+
context "when the criteria has limiting options" do
|
950
|
+
|
951
|
+
let!(:person_two) do
|
952
|
+
Person.create!(age: 2)
|
953
|
+
end
|
954
|
+
|
955
|
+
let!(:game_three) do
|
956
|
+
person_two.create_game(name: "Skyrim")
|
957
|
+
end
|
958
|
+
|
959
|
+
let!(:criteria) do
|
960
|
+
Person.where(id: person.id).includes(:game).asc(:age).limit(1)
|
961
|
+
end
|
962
|
+
|
963
|
+
let(:context) do
|
964
|
+
criteria.context
|
965
|
+
end
|
966
|
+
|
967
|
+
before do
|
968
|
+
expect(context).to receive(:eager_load).with([ person ]).once.and_call_original
|
969
|
+
end
|
970
|
+
|
971
|
+
let!(:documents) do
|
972
|
+
criteria.entries
|
973
|
+
end
|
974
|
+
|
975
|
+
it "returns the correct documents" do
|
976
|
+
expect(documents).to eq([ person ])
|
977
|
+
end
|
978
|
+
end
|
979
|
+
end
|
980
|
+
|
981
|
+
context "when including a belongs to" do
|
982
|
+
|
983
|
+
let(:person_two) do
|
984
|
+
Person.create!(age: 2)
|
985
|
+
end
|
986
|
+
|
987
|
+
let!(:game_one) do
|
988
|
+
person.create_game(name: "one")
|
989
|
+
end
|
990
|
+
|
991
|
+
let!(:game_two) do
|
992
|
+
person_two.create_game(name: "two")
|
993
|
+
end
|
994
|
+
|
995
|
+
context "when providing no options" do
|
996
|
+
|
997
|
+
let!(:criteria) do
|
998
|
+
Game.includes(:person)
|
999
|
+
end
|
1000
|
+
|
1001
|
+
let(:context) do
|
1002
|
+
criteria.context
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
before do
|
1006
|
+
expect(context).to receive(:preload).twice.and_call_original
|
1007
|
+
end
|
1008
|
+
|
1009
|
+
let!(:documents) do
|
1010
|
+
criteria.entries
|
1011
|
+
end
|
1012
|
+
|
1013
|
+
it "returns the correct documents" do
|
1014
|
+
expect(criteria).to eq([ game_one, game_two ])
|
1015
|
+
end
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
context "when the criteria has limiting options" do
|
1019
|
+
|
1020
|
+
let!(:criteria) do
|
1021
|
+
Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
let(:context) do
|
1025
|
+
criteria.context
|
1026
|
+
end
|
1027
|
+
|
1028
|
+
before do
|
1029
|
+
expect(context).to receive(:eager_load).with([ game_one ]).once.and_call_original
|
1030
|
+
end
|
1031
|
+
|
1032
|
+
let!(:documents) do
|
1033
|
+
criteria.entries
|
1034
|
+
end
|
1035
|
+
|
1036
|
+
it "returns the correct documents" do
|
1037
|
+
expect(documents).to eq([ game_one ])
|
1038
|
+
end
|
1039
|
+
end
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
context "when including multiples in the same criteria" do
|
1043
|
+
|
1044
|
+
let!(:post_one) do
|
1045
|
+
person.posts.create!(title: "one")
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
let!(:post_two) do
|
1049
|
+
person.posts.create!(title: "two")
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
let!(:game_one) do
|
1053
|
+
person.create_game(name: "one")
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
let!(:game_two) do
|
1057
|
+
person.create_game(name: "two")
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
let!(:criteria) do
|
1061
|
+
Person.includes(:posts, :game).asc(:age)
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
let(:context) do
|
1065
|
+
criteria.context
|
1066
|
+
end
|
1067
|
+
|
1068
|
+
before do
|
1069
|
+
expect(context).to receive(:preload).twice.and_call_original
|
1070
|
+
end
|
1071
|
+
|
1072
|
+
let!(:documents) do
|
1073
|
+
criteria.entries
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
it "returns the correct documents" do
|
1077
|
+
expect(criteria).to eq([ person ])
|
1078
|
+
end
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
context "when including nested referenced associations" do
|
1082
|
+
|
1083
|
+
context "when using a has_one association" do
|
1084
|
+
before(:all) do
|
1085
|
+
class A
|
1086
|
+
include Mongoid::Document
|
1087
|
+
has_one :b
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
class B
|
1091
|
+
include Mongoid::Document
|
1092
|
+
belongs_to :a
|
1093
|
+
has_one :c
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
class C
|
1097
|
+
include Mongoid::Document
|
1098
|
+
belongs_to :b
|
1099
|
+
has_one :d
|
1100
|
+
end
|
1101
|
+
|
1102
|
+
class D
|
1103
|
+
include Mongoid::Document
|
1104
|
+
belongs_to :c
|
1105
|
+
end
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
after(:all) do
|
1109
|
+
Object.send(:remove_const, :A)
|
1110
|
+
Object.send(:remove_const, :B)
|
1111
|
+
Object.send(:remove_const, :C)
|
1112
|
+
Object.send(:remove_const, :D)
|
1113
|
+
end
|
1114
|
+
|
1115
|
+
let!(:a) do
|
1116
|
+
A.create!
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
let!(:b) do
|
1120
|
+
B.create!
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
let!(:c) do
|
1124
|
+
C.create!
|
1125
|
+
end
|
1126
|
+
|
1127
|
+
let!(:d) do
|
1128
|
+
D.create!
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
before do
|
1132
|
+
c.d = d
|
1133
|
+
b.c = c
|
1134
|
+
a.b = b
|
1135
|
+
end
|
1136
|
+
|
1137
|
+
context "when including the belongs_to assocation" do
|
1138
|
+
let!(:result) do
|
1139
|
+
C.includes(b: :a).first
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
it "finds the right document" do
|
1143
|
+
expect(result).to eq(c)
|
1144
|
+
expect(result.b).to eq(c.b)
|
1145
|
+
expect(result.b.a).to eq(c.b.a)
|
1146
|
+
end
|
1147
|
+
|
1148
|
+
it "does not execute a query" do
|
1149
|
+
expect_no_queries do
|
1150
|
+
result.b.a
|
1151
|
+
end
|
1152
|
+
end
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
context "when including a doubly-nested belongs_to assocation" do
|
1156
|
+
let!(:result) do
|
1157
|
+
D.includes(c: { b: :a }).first
|
1158
|
+
end
|
1159
|
+
|
1160
|
+
it "finds the right document" do
|
1161
|
+
expect(result).to eq(d)
|
1162
|
+
expect(result.c).to eq(d.c)
|
1163
|
+
expect(result.c.b).to eq(d.c.b)
|
1164
|
+
expect(result.c.b.a).to eq(d.c.b.a)
|
1165
|
+
end
|
1166
|
+
|
1167
|
+
it "does not execute a query" do
|
1168
|
+
expect_no_queries do
|
1169
|
+
result.c.b.a
|
1170
|
+
end
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
context "when including the has_many assocation" do
|
1175
|
+
let!(:result) do
|
1176
|
+
A.includes(b: :c).first
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
it "finds the right document" do
|
1180
|
+
expect(result).to eq(a)
|
1181
|
+
expect(result.b).to eq(a.b)
|
1182
|
+
expect(result.b.c).to eq(a.b.c)
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
it "does not executes a query" do
|
1186
|
+
expect_no_queries do
|
1187
|
+
result.b.c
|
1188
|
+
end
|
1189
|
+
end
|
1190
|
+
end
|
1191
|
+
|
1192
|
+
context "when including a doubly-nested has_many assocation" do
|
1193
|
+
let!(:result) do
|
1194
|
+
A.includes(b: { c: :d }).first
|
1195
|
+
end
|
1196
|
+
|
1197
|
+
it "finds the right document" do
|
1198
|
+
expect(result).to eq(a)
|
1199
|
+
expect(result.b).to eq(a.b)
|
1200
|
+
expect(result.b.c).to eq(a.b.c)
|
1201
|
+
expect(result.b.c.d).to eq(a.b.c.d)
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
it "does not execute a query" do
|
1205
|
+
expect_no_queries do
|
1206
|
+
result.b.c.d
|
1207
|
+
end
|
1208
|
+
end
|
1209
|
+
end
|
1210
|
+
|
1211
|
+
context "when there are multiple documents" do
|
1212
|
+
let!(:as) do
|
1213
|
+
res = 9.times.map do |i|
|
1214
|
+
A.create!.tap do |a|
|
1215
|
+
a.b = B.create!.tap do |b|
|
1216
|
+
b.c = C.create!
|
1217
|
+
end
|
1218
|
+
end
|
1219
|
+
end
|
1220
|
+
[a, *res]
|
1221
|
+
end
|
1222
|
+
|
1223
|
+
let!(:results) do
|
1224
|
+
A.includes(b: :c).entries.sort
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
it "finds the right document" do
|
1228
|
+
as.length.times do |i|
|
1229
|
+
expect(as[i]).to eq(results[i])
|
1230
|
+
expect(as[i].b).to eq(results[i].b)
|
1231
|
+
expect(as[i].b.c).to eq(results[i].b.c)
|
1232
|
+
end
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it "does not execute a query" do
|
1236
|
+
expect_no_queries do
|
1237
|
+
results.each do |a|
|
1238
|
+
a.b.c
|
1239
|
+
end
|
1240
|
+
end
|
1241
|
+
end
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
context "when there are multiple associations" do
|
1245
|
+
before(:all) do
|
1246
|
+
class A
|
1247
|
+
has_one :c
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
class C
|
1251
|
+
belongs_to :a
|
1252
|
+
end
|
1253
|
+
end
|
1254
|
+
|
1255
|
+
let(:c2) { C.create! }
|
1256
|
+
let(:d2) { D.create! }
|
1257
|
+
|
1258
|
+
before do
|
1259
|
+
a.c = c2
|
1260
|
+
a.c.d = d2
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
let!(:results) do
|
1264
|
+
A.includes(b: { c: :d }, c: :d).first
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
it "finds the right document" do
|
1268
|
+
expect(results).to eq(a)
|
1269
|
+
expect(results.b).to eq(a.b)
|
1270
|
+
expect(results.b.c).to eq(a.b.c)
|
1271
|
+
expect(results.b.c.d).to eq(a.b.c.d)
|
1272
|
+
expect(results.c).to eq(a.c)
|
1273
|
+
expect(results.c.d).to eq(a.c.d)
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
it "does not execute a query" do
|
1277
|
+
expect_no_queries do
|
1278
|
+
results.c.d
|
1279
|
+
results.b.c.d
|
1280
|
+
end
|
1281
|
+
end
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
context "when using a has_many association" do
|
1287
|
+
|
1288
|
+
let!(:user) do
|
1289
|
+
IncUser.create!(posts: posts, comments: user_comments)
|
1290
|
+
end
|
1291
|
+
|
1292
|
+
let!(:posts) do
|
1293
|
+
[ IncPost.create!(comments: post_comments) ]
|
1294
|
+
end
|
1295
|
+
|
1296
|
+
let!(:user_comments) do
|
1297
|
+
2.times.map{ IncComment.create! }
|
1298
|
+
end
|
1299
|
+
|
1300
|
+
let!(:post_comments) do
|
1301
|
+
2.times.map{ IncComment.create! }
|
1302
|
+
end
|
1303
|
+
|
1304
|
+
context "when including the same class twice" do
|
1305
|
+
let!(:results) do
|
1306
|
+
IncPost.includes({ user: :comments }, :comments).entries.sort
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
it "finds the right documents" do
|
1310
|
+
posts.length.times do |i|
|
1311
|
+
expect(posts[i]).to eq(results[i])
|
1312
|
+
expect(posts[i].user).to eq(results[i].user)
|
1313
|
+
expect(posts[i].user.comments).to eq(results[i].user.comments)
|
1314
|
+
expect(posts[i].comments).to eq(results[i].comments)
|
1315
|
+
end
|
1316
|
+
end
|
1317
|
+
|
1318
|
+
it "does not execute a query" do
|
1319
|
+
expect_no_queries do
|
1320
|
+
results.each do |res|
|
1321
|
+
res.user
|
1322
|
+
res.user.comments.to_a
|
1323
|
+
res.comments.to_a
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
end
|
1328
|
+
|
1329
|
+
context "when the association chain has a class name twice" do
|
1330
|
+
let!(:thread) { IncThread.create!(comments: user_comments) }
|
1331
|
+
|
1332
|
+
let!(:result) do
|
1333
|
+
IncThread.includes(comments: { user: { posts: :comments } }).first
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
it "finds the right document" do
|
1337
|
+
expect(result).to eq(thread)
|
1338
|
+
result.comments.length.times do |i|
|
1339
|
+
c1 = result.comments[i]
|
1340
|
+
c2 = thread.comments[i]
|
1341
|
+
expect(c1).to eq(c2)
|
1342
|
+
expect(c1.user).to eq(c2.user)
|
1343
|
+
c1.user.posts.length.times do |i|
|
1344
|
+
p1 = c1.user.posts[i]
|
1345
|
+
p2 = c2.user.posts[i]
|
1346
|
+
|
1347
|
+
expect(p1).to eq(p2)
|
1348
|
+
expect(p1.comments).to eq(p2.comments)
|
1349
|
+
end
|
1350
|
+
end
|
1351
|
+
end
|
1352
|
+
|
1353
|
+
it "does not execute a query" do
|
1354
|
+
expect_no_queries do
|
1355
|
+
result.comments.each do |comment|
|
1356
|
+
comment.user.posts.each do |post|
|
1357
|
+
post.comments.to_a
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
end
|
1361
|
+
end
|
1362
|
+
end
|
1363
|
+
end
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
describe "#inclusions" do
|
1367
|
+
|
1368
|
+
let(:criteria) do
|
1369
|
+
Band.includes(:records)
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
let(:association) do
|
1373
|
+
Band.relations["records"]
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
it "returns the inclusions" do
|
1377
|
+
expect(criteria.inclusions).to eq([ association ])
|
1378
|
+
end
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
describe "#inclusions=" do
|
1382
|
+
|
1383
|
+
let(:criteria) do
|
1384
|
+
Band.all
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
let(:association) do
|
1388
|
+
Band.relations["records"]
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
before do
|
1392
|
+
criteria.inclusions = [ association ]
|
1393
|
+
end
|
1394
|
+
|
1395
|
+
it "sets the inclusions" do
|
1396
|
+
expect(criteria.inclusions).to eq([ association ])
|
1397
|
+
end
|
1398
|
+
end
|
1399
|
+
|
1400
|
+
context "When multiple associations reference the same class" do
|
1401
|
+
before do
|
1402
|
+
IncBlog.create(
|
1403
|
+
posts: [
|
1404
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1405
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1406
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1407
|
+
],
|
1408
|
+
highlighted_post: IncBlogPost.create(author: IncAuthor.create)
|
1409
|
+
)
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
let!(:result) do
|
1413
|
+
IncBlog.includes(:posts, highlighted_post: :author).first
|
1414
|
+
end
|
1415
|
+
|
1416
|
+
it "does not execute a query" do
|
1417
|
+
expect_no_queries do
|
1418
|
+
result.posts.to_a
|
1419
|
+
result.highlighted_post
|
1420
|
+
end
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
it "executes a query for the non-retrieved elements" do
|
1424
|
+
expect_query(3) do
|
1425
|
+
result.posts.each do |post|
|
1426
|
+
post.author
|
1427
|
+
end
|
1428
|
+
end
|
1429
|
+
end
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
context "When multiple parent_inclusions for the same association" do
|
1433
|
+
before do
|
1434
|
+
IncBlog.create(
|
1435
|
+
posts: [
|
1436
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1437
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1438
|
+
IncBlogPost.create(author: IncAuthor.create),
|
1439
|
+
],
|
1440
|
+
highlighted_post: IncBlogPost.create(author: IncAuthor.create),
|
1441
|
+
pinned_post: IncBlogPost.create(author: IncAuthor.create)
|
1442
|
+
)
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
let!(:result) do
|
1446
|
+
IncBlog.includes(:posts, highlighted_post: :author, pinned_post: :author).first
|
1447
|
+
end
|
1448
|
+
|
1449
|
+
it "does not execute a query" do
|
1450
|
+
expect_no_queries do
|
1451
|
+
result.posts.to_a
|
1452
|
+
result.highlighted_post
|
1453
|
+
result.pinned_post
|
1454
|
+
end
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
it "executes a query for the non-retrieved elements" do
|
1458
|
+
expect_query(3) do
|
1459
|
+
result.posts.each do |post|
|
1460
|
+
post.author
|
1461
|
+
end
|
1462
|
+
end
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
context "when including an association and using each twice on a criteria" do
|
1466
|
+
|
1467
|
+
let(:criteria) { IncPost.all.includes(:person) }
|
1468
|
+
|
1469
|
+
before do
|
1470
|
+
p = IncPerson.create!(name: "name")
|
1471
|
+
4.times { IncPost.create!(person: p)}
|
1472
|
+
criteria
|
1473
|
+
expect_query(2) do
|
1474
|
+
criteria.each(&:person)
|
1475
|
+
end
|
1476
|
+
end
|
1477
|
+
|
1478
|
+
# The reason we are checking for two operations here is:
|
1479
|
+
# - The first operation gets all of the posts
|
1480
|
+
# - The second operation gets the person from the first post
|
1481
|
+
# Now, all subsequent posts should use the eager loaded person when
|
1482
|
+
# trying to retrieve their person.
|
1483
|
+
# MONGOID-3942 reported that after iterating the criteria a second time,
|
1484
|
+
# the posts would not get the eager loaded person.
|
1485
|
+
it "eager loads the criteria" do
|
1486
|
+
expect_query(2) do
|
1487
|
+
criteria.each(&:person)
|
1488
|
+
end
|
1489
|
+
end
|
1490
|
+
end
|
1491
|
+
end
|
1492
|
+
end
|