mongoid 8.1.10 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +1 -0
- data/LICENSE +1 -1
- data/README.md +4 -9
- data/Rakefile +63 -45
- data/lib/config/locales/en.yml +66 -5
- data/lib/mongoid/association/accessors.rb +16 -20
- data/lib/mongoid/association/bindable.rb +27 -8
- data/lib/mongoid/association/builders.rb +3 -2
- data/lib/mongoid/association/constrainable.rb +1 -0
- data/lib/mongoid/association/depending.rb +16 -1
- data/lib/mongoid/association/eager.rb +160 -0
- data/lib/mongoid/association/eager_loadable.rb +15 -7
- data/lib/mongoid/association/embedded/batchable.rb +6 -7
- data/lib/mongoid/association/embedded/cyclic.rb +1 -0
- data/lib/mongoid/association/embedded/eager.rb +23 -0
- data/lib/mongoid/association/embedded/embedded_in/binding.rb +5 -4
- data/lib/mongoid/association/embedded/embedded_in/buildable.rb +1 -0
- data/lib/mongoid/association/embedded/embedded_in/proxy.rb +21 -7
- data/lib/mongoid/association/embedded/embedded_in.rb +7 -0
- data/lib/mongoid/association/embedded/embeds_many/binding.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_many/buildable.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +134 -144
- data/lib/mongoid/association/embedded/embeds_many.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_one/binding.rb +3 -2
- data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -0
- data/lib/mongoid/association/embedded/embeds_one/proxy.rb +112 -54
- data/lib/mongoid/association/embedded/embeds_one.rb +1 -0
- data/lib/mongoid/association/embedded.rb +2 -0
- data/lib/mongoid/association/macros.rb +17 -14
- data/lib/mongoid/association/many.rb +1 -0
- data/lib/mongoid/association/marshalable.rb +4 -0
- data/lib/mongoid/association/nested/many.rb +8 -3
- data/lib/mongoid/association/nested/nested_buildable.rb +32 -0
- data/lib/mongoid/association/nested/one.rb +6 -3
- data/lib/mongoid/association/nested.rb +1 -0
- data/lib/mongoid/association/one.rb +1 -0
- data/lib/mongoid/association/options.rb +9 -2
- data/lib/mongoid/association/proxy.rb +30 -18
- data/lib/mongoid/association/referenced/auto_save.rb +6 -2
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -0
- data/lib/mongoid/association/referenced/belongs_to/eager.rb +2 -1
- data/lib/mongoid/association/referenced/belongs_to/proxy.rb +19 -14
- data/lib/mongoid/association/referenced/belongs_to.rb +2 -1
- data/lib/mongoid/association/referenced/counter_cache.rb +7 -2
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/binding.rb +15 -3
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/buildable.rb +1 -0
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/eager.rb +2 -1
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +132 -94
- data/lib/mongoid/association/referenced/has_and_belongs_to_many.rb +8 -3
- data/lib/mongoid/association/referenced/has_many/binding.rb +1 -0
- data/lib/mongoid/association/referenced/has_many/buildable.rb +1 -0
- data/lib/mongoid/association/referenced/has_many/eager.rb +2 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +43 -27
- data/lib/mongoid/association/referenced/has_many/proxy.rb +131 -104
- data/lib/mongoid/association/referenced/has_many.rb +2 -1
- data/lib/mongoid/association/referenced/has_one/binding.rb +1 -0
- data/lib/mongoid/association/referenced/has_one/buildable.rb +1 -0
- data/lib/mongoid/association/referenced/has_one/eager.rb +3 -3
- data/lib/mongoid/association/referenced/has_one/proxy.rb +37 -28
- data/lib/mongoid/association/referenced/has_one.rb +5 -1
- data/lib/mongoid/association/referenced/syncable.rb +7 -6
- data/lib/mongoid/association/referenced.rb +1 -0
- data/lib/mongoid/association/reflections.rb +5 -4
- data/lib/mongoid/association/relatable.rb +10 -4
- data/lib/mongoid/association.rb +5 -0
- data/lib/mongoid/atomic/modifiers.rb +1 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +2 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -0
- data/lib/mongoid/atomic/paths/embedded.rb +1 -0
- data/lib/mongoid/atomic/paths/root.rb +1 -0
- data/lib/mongoid/atomic/paths.rb +1 -0
- data/lib/mongoid/atomic.rb +23 -62
- data/lib/mongoid/atomic_update_preparer.rb +88 -0
- data/lib/mongoid/attributes/dynamic.rb +1 -0
- data/lib/mongoid/attributes/embedded.rb +34 -0
- data/lib/mongoid/attributes/nested.rb +3 -2
- data/lib/mongoid/attributes/processing.rb +11 -10
- data/lib/mongoid/attributes/projector.rb +1 -0
- data/lib/mongoid/attributes/readonly.rb +4 -8
- data/lib/mongoid/attributes.rb +6 -4
- data/lib/mongoid/cacheable.rb +2 -1
- data/lib/mongoid/changeable.rb +58 -49
- data/lib/mongoid/clients/factory.rb +37 -1
- data/lib/mongoid/clients/options.rb +113 -3
- data/lib/mongoid/clients/sessions.rb +245 -64
- data/lib/mongoid/clients/storage_options.rb +37 -1
- data/lib/mongoid/clients/validators/storage.rb +1 -0
- data/lib/mongoid/clients/validators.rb +1 -0
- data/lib/mongoid/clients.rb +36 -4
- data/lib/mongoid/collection_configurable.rb +1 -0
- data/lib/mongoid/composable.rb +5 -0
- data/lib/mongoid/config/defaults.rb +16 -36
- data/lib/mongoid/config/encryption.rb +213 -0
- data/lib/mongoid/config/environment.rb +2 -5
- data/lib/mongoid/config/introspection.rb +152 -0
- data/lib/mongoid/config/options.rb +8 -3
- data/lib/mongoid/config/validators/async_query_executor.rb +12 -2
- data/lib/mongoid/config/validators/client.rb +1 -0
- data/lib/mongoid/config/validators/option.rb +1 -0
- data/lib/mongoid/config/validators.rb +1 -0
- data/lib/mongoid/config.rb +57 -91
- data/lib/mongoid/contextual/aggregable/memory.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +2 -5
- data/lib/mongoid/contextual/aggregable/none.rb +1 -0
- data/lib/mongoid/contextual/aggregable.rb +1 -0
- data/lib/mongoid/contextual/atomic.rb +98 -11
- data/lib/mongoid/contextual/command.rb +3 -0
- data/lib/mongoid/contextual/map_reduce.rb +6 -0
- data/lib/mongoid/contextual/memory.rb +45 -42
- data/lib/mongoid/contextual/mongo/documents_loader.rb +3 -2
- data/lib/mongoid/contextual/mongo.rb +32 -60
- data/lib/mongoid/contextual/none.rb +15 -32
- data/lib/mongoid/contextual/queryable.rb +4 -0
- data/lib/mongoid/contextual.rb +4 -0
- data/lib/mongoid/copyable.rb +3 -2
- data/lib/mongoid/criteria/findable.rb +44 -4
- data/lib/mongoid/criteria/includable.rb +5 -4
- data/lib/mongoid/criteria/inspectable.rb +4 -0
- data/lib/mongoid/criteria/marshalable.rb +4 -0
- data/lib/mongoid/criteria/modifiable.rb +5 -0
- data/lib/mongoid/criteria/options.rb +1 -0
- data/lib/mongoid/criteria/permission.rb +5 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +1 -0
- data/lib/mongoid/criteria/queryable/expandable.rb +1 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +3 -5
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/date.rb +4 -3
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +3 -16
- data/lib/mongoid/criteria/queryable/extensions/object.rb +4 -1
- data/lib/mongoid/criteria/queryable/extensions/range.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +7 -1
- data/lib/mongoid/criteria/queryable/extensions/set.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/string.rb +15 -3
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/time.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +3 -1
- data/lib/mongoid/criteria/queryable/extensions.rb +1 -0
- data/lib/mongoid/criteria/queryable/key.rb +10 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +1 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +1 -0
- data/lib/mongoid/criteria/queryable/optional.rb +1 -0
- data/lib/mongoid/criteria/queryable/options.rb +1 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +1 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +12 -27
- data/lib/mongoid/criteria/queryable/selector.rb +5 -2
- data/lib/mongoid/criteria/queryable/smash.rb +1 -0
- data/lib/mongoid/criteria/queryable/storable.rb +4 -3
- data/lib/mongoid/criteria/queryable.rb +1 -0
- data/lib/mongoid/criteria/scopable.rb +5 -0
- data/lib/mongoid/criteria/translator.rb +1 -0
- data/lib/mongoid/criteria.rb +37 -10
- data/lib/mongoid/deprecable.rb +1 -0
- data/lib/mongoid/deprecation.rb +8 -4
- data/lib/mongoid/document.rb +171 -125
- data/lib/mongoid/encryptable.rb +53 -0
- data/lib/mongoid/equality.rb +2 -22
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -0
- data/lib/mongoid/errors/attribute_not_loaded.rb +34 -0
- data/lib/mongoid/errors/callback.rb +1 -0
- data/lib/mongoid/errors/create_collection_failure.rb +1 -0
- data/lib/mongoid/errors/criteria_argument_required.rb +1 -0
- data/lib/mongoid/errors/delete_restriction.rb +1 -0
- data/lib/mongoid/errors/document_not_destroyed.rb +1 -0
- data/lib/mongoid/errors/document_not_found.rb +1 -0
- data/lib/mongoid/errors/drop_collection_failure.rb +1 -0
- data/lib/mongoid/errors/empty_config_file.rb +1 -0
- data/lib/mongoid/errors/immutable_attribute.rb +1 -0
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -0
- data/lib/mongoid/errors/invalid_async_query_executor.rb +1 -0
- data/lib/mongoid/errors/invalid_auto_encryption_configuration.rb +33 -0
- data/lib/mongoid/errors/invalid_collection.rb +1 -0
- data/lib/mongoid/errors/invalid_config_file.rb +1 -0
- data/lib/mongoid/errors/invalid_config_option.rb +1 -0
- data/lib/mongoid/errors/invalid_dependent_strategy.rb +1 -0
- data/lib/mongoid/errors/invalid_discriminator_key_target.rb +1 -0
- data/lib/mongoid/errors/invalid_dot_dollar_assignment.rb +1 -0
- data/lib/mongoid/errors/invalid_elem_match_operator.rb +1 -0
- data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +6 -4
- data/lib/mongoid/errors/invalid_estimated_count_scoping.rb +27 -0
- data/lib/mongoid/errors/invalid_expression_operator.rb +1 -0
- data/lib/mongoid/errors/invalid_field.rb +1 -0
- data/lib/mongoid/errors/invalid_field_operator.rb +1 -0
- data/lib/mongoid/errors/invalid_field_option.rb +1 -0
- data/lib/mongoid/errors/invalid_field_type.rb +1 -0
- data/lib/mongoid/errors/invalid_find.rb +1 -0
- data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +1 -0
- data/lib/mongoid/errors/invalid_includes.rb +1 -0
- data/lib/mongoid/errors/invalid_index.rb +1 -0
- data/lib/mongoid/errors/invalid_options.rb +1 -0
- data/lib/mongoid/errors/invalid_path.rb +1 -0
- data/lib/mongoid/errors/invalid_persistence_option.rb +1 -0
- data/lib/mongoid/errors/invalid_query.rb +1 -0
- data/lib/mongoid/errors/invalid_relation.rb +1 -0
- data/lib/mongoid/errors/invalid_relation_option.rb +1 -0
- data/lib/mongoid/errors/invalid_scope.rb +1 -0
- data/lib/mongoid/errors/invalid_session_nesting.rb +17 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +1 -1
- data/lib/mongoid/errors/invalid_storage_options.rb +1 -0
- data/lib/mongoid/errors/invalid_time.rb +1 -0
- data/lib/mongoid/errors/invalid_transaction_nesting.rb +17 -0
- data/lib/mongoid/errors/inverse_not_found.rb +1 -0
- data/lib/mongoid/errors/mixed_client_configuration.rb +1 -0
- data/lib/mongoid/errors/mixed_relations.rb +1 -0
- data/lib/mongoid/errors/mongoid_error.rb +4 -3
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +1 -0
- data/lib/mongoid/errors/no_client_config.rb +1 -0
- data/lib/mongoid/errors/no_client_database.rb +1 -0
- data/lib/mongoid/errors/no_client_hosts.rb +1 -0
- data/lib/mongoid/errors/no_clients_config.rb +1 -0
- data/lib/mongoid/errors/no_default_client.rb +1 -0
- data/lib/mongoid/errors/no_environment.rb +1 -0
- data/lib/mongoid/errors/no_map_reduce_output.rb +1 -0
- data/lib/mongoid/errors/no_metadata.rb +1 -0
- data/lib/mongoid/errors/no_parent.rb +1 -0
- data/lib/mongoid/errors/readonly_attribute.rb +1 -0
- data/lib/mongoid/errors/readonly_document.rb +1 -0
- data/lib/mongoid/errors/rollback.rb +15 -0
- data/lib/mongoid/errors/scope_overwrite.rb +1 -0
- data/lib/mongoid/errors/sessions_not_supported.rb +17 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +1 -0
- data/lib/mongoid/errors/transaction_error.rb +25 -0
- data/lib/mongoid/errors/transactions_not_supported.rb +17 -0
- data/lib/mongoid/errors/unknown_attribute.rb +1 -0
- data/lib/mongoid/errors/unknown_model.rb +1 -0
- data/lib/mongoid/errors/unsaved_document.rb +1 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +1 -0
- data/lib/mongoid/errors/validations.rb +1 -0
- data/lib/mongoid/errors.rb +10 -1
- data/lib/mongoid/evolvable.rb +1 -0
- data/lib/mongoid/extensions/array.rb +10 -24
- data/lib/mongoid/extensions/big_decimal.rb +14 -6
- data/lib/mongoid/extensions/binary.rb +3 -0
- data/lib/mongoid/extensions/boolean.rb +3 -0
- data/lib/mongoid/extensions/date.rb +7 -2
- data/lib/mongoid/extensions/date_time.rb +4 -6
- data/lib/mongoid/extensions/decimal128.rb +3 -0
- data/lib/mongoid/extensions/false_class.rb +5 -2
- data/lib/mongoid/extensions/float.rb +4 -1
- data/lib/mongoid/extensions/hash.rb +21 -143
- data/lib/mongoid/extensions/integer.rb +6 -1
- data/lib/mongoid/extensions/module.rb +4 -1
- data/lib/mongoid/extensions/nil_class.rb +5 -2
- data/lib/mongoid/extensions/object.rb +23 -35
- data/lib/mongoid/extensions/object_id.rb +3 -0
- data/lib/mongoid/extensions/range.rb +9 -6
- data/lib/mongoid/extensions/raw_value.rb +34 -0
- data/lib/mongoid/extensions/regexp.rb +3 -0
- data/lib/mongoid/extensions/set.rb +13 -2
- data/lib/mongoid/extensions/string.rb +18 -10
- data/lib/mongoid/extensions/symbol.rb +5 -0
- data/lib/mongoid/extensions/time.rb +7 -19
- data/lib/mongoid/extensions/time_with_zone.rb +6 -2
- data/lib/mongoid/extensions/true_class.rb +5 -2
- data/lib/mongoid/extensions.rb +2 -32
- data/lib/mongoid/factory.rb +134 -40
- data/lib/mongoid/fields/encrypted.rb +48 -0
- data/lib/mongoid/fields/foreign_key.rb +29 -3
- data/lib/mongoid/fields/localized.rb +6 -0
- data/lib/mongoid/fields/standard.rb +5 -0
- data/lib/mongoid/fields/validators/macro.rb +3 -1
- data/lib/mongoid/fields/validators.rb +1 -0
- data/lib/mongoid/fields.rb +41 -46
- data/lib/mongoid/findable.rb +2 -2
- data/lib/mongoid/indexable/specification.rb +55 -19
- data/lib/mongoid/indexable/validators/options.rb +1 -0
- data/lib/mongoid/indexable.rb +1 -0
- data/lib/mongoid/inspectable.rb +32 -0
- data/lib/mongoid/interceptable.rb +18 -8
- data/lib/mongoid/loadable.rb +83 -0
- data/lib/mongoid/loggable.rb +1 -0
- data/lib/mongoid/matchable.rb +1 -0
- data/lib/mongoid/matcher/all.rb +15 -0
- data/lib/mongoid/matcher/and.rb +14 -0
- data/lib/mongoid/matcher/bits.rb +19 -0
- data/lib/mongoid/matcher/bits_all_clear.rb +21 -0
- data/lib/mongoid/matcher/bits_all_set.rb +21 -0
- data/lib/mongoid/matcher/bits_any_clear.rb +21 -0
- data/lib/mongoid/matcher/bits_any_set.rb +21 -0
- data/lib/mongoid/matcher/elem_match.rb +15 -0
- data/lib/mongoid/matcher/elem_match_expression.rb +14 -2
- data/lib/mongoid/matcher/eq.rb +15 -0
- data/lib/mongoid/matcher/eq_impl.rb +33 -16
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +14 -2
- data/lib/mongoid/matcher/exists.rb +15 -0
- data/lib/mongoid/matcher/expression.rb +13 -0
- data/lib/mongoid/matcher/expression_operator.rb +14 -0
- data/lib/mongoid/matcher/field_expression.rb +15 -0
- data/lib/mongoid/matcher/field_operator.rb +24 -0
- data/lib/mongoid/matcher/gt.rb +15 -0
- data/lib/mongoid/matcher/gte.rb +15 -0
- data/lib/mongoid/matcher/in.rb +15 -0
- data/lib/mongoid/matcher/lt.rb +15 -0
- data/lib/mongoid/matcher/lte.rb +15 -0
- data/lib/mongoid/matcher/mod.rb +16 -0
- data/lib/mongoid/matcher/ne.rb +15 -0
- data/lib/mongoid/matcher/nin.rb +15 -0
- data/lib/mongoid/matcher/nor.rb +14 -0
- data/lib/mongoid/matcher/not.rb +16 -0
- data/lib/mongoid/matcher/or.rb +14 -0
- data/lib/mongoid/matcher/regex.rb +24 -0
- data/lib/mongoid/matcher/size.rb +16 -0
- data/lib/mongoid/matcher/type.rb +25 -0
- data/lib/mongoid/matcher.rb +5 -15
- data/lib/mongoid/persistable/creatable.rb +14 -9
- data/lib/mongoid/persistable/deletable.rb +7 -2
- data/lib/mongoid/persistable/destroyable.rb +34 -7
- data/lib/mongoid/persistable/incrementable.rb +2 -1
- data/lib/mongoid/persistable/logical.rb +1 -0
- data/lib/mongoid/persistable/maxable.rb +37 -0
- data/lib/mongoid/persistable/minable.rb +37 -0
- data/lib/mongoid/persistable/multipliable.rb +36 -0
- data/lib/mongoid/persistable/poppable.rb +1 -0
- data/lib/mongoid/persistable/pullable.rb +1 -0
- data/lib/mongoid/persistable/pushable.rb +1 -0
- data/lib/mongoid/persistable/renamable.rb +1 -0
- data/lib/mongoid/persistable/savable.rb +1 -0
- data/lib/mongoid/persistable/settable.rb +1 -0
- data/lib/mongoid/persistable/unsettable.rb +1 -0
- data/lib/mongoid/persistable/updatable.rb +37 -18
- data/lib/mongoid/persistable/upsertable.rb +20 -7
- data/lib/mongoid/persistable.rb +11 -1
- data/lib/mongoid/persistence_context.rb +46 -6
- data/lib/mongoid/positional.rb +1 -0
- data/lib/mongoid/railtie.rb +24 -1
- data/lib/mongoid/railties/bson_object_id_serializer.rb +39 -0
- data/lib/mongoid/railties/console_sandbox.rb +42 -0
- data/lib/mongoid/railties/controller_runtime.rb +20 -4
- data/lib/mongoid/railties/database.rake +12 -0
- data/lib/mongoid/reloadable.rb +38 -30
- data/lib/mongoid/scopable.rb +19 -23
- data/lib/mongoid/search_indexable.rb +167 -0
- data/lib/mongoid/selectable.rb +1 -0
- data/lib/mongoid/serializable.rb +8 -7
- data/lib/mongoid/shardable.rb +1 -0
- data/lib/mongoid/stateful.rb +9 -3
- data/lib/mongoid/stringified_symbol.rb +19 -6
- data/lib/mongoid/tasks/database.rake +13 -0
- data/lib/mongoid/tasks/database.rb +63 -0
- data/lib/mongoid/tasks/encryption.rake +59 -0
- data/lib/mongoid/tasks/encryption.rb +108 -0
- data/lib/mongoid/threaded/lifecycle.rb +1 -0
- data/lib/mongoid/threaded.rb +94 -30
- data/lib/mongoid/timestamps/created/short.rb +1 -0
- data/lib/mongoid/timestamps/created.rb +5 -11
- data/lib/mongoid/timestamps/short.rb +1 -0
- data/lib/mongoid/timestamps/timeless.rb +29 -0
- data/lib/mongoid/timestamps/updated/short.rb +1 -0
- data/lib/mongoid/timestamps/updated.rb +2 -1
- data/lib/mongoid/timestamps.rb +1 -0
- data/lib/mongoid/touchable.rb +154 -49
- data/lib/mongoid/traversable.rb +127 -122
- data/lib/mongoid/utils.rb +32 -2
- data/lib/mongoid/validatable/associated.rb +4 -6
- data/lib/mongoid/validatable/format.rb +1 -0
- data/lib/mongoid/validatable/length.rb +1 -0
- data/lib/mongoid/validatable/localizable.rb +1 -0
- data/lib/mongoid/validatable/macros.rb +5 -0
- data/lib/mongoid/validatable/presence.rb +1 -0
- data/lib/mongoid/validatable/queryable.rb +9 -0
- data/lib/mongoid/validatable/uniqueness.rb +2 -1
- data/lib/mongoid/validatable.rb +3 -2
- data/lib/mongoid/version.rb +2 -1
- data/lib/mongoid/warnings.rb +9 -16
- data/lib/mongoid.rb +38 -5
- data/lib/rails/generators/mongoid/config/config_generator.rb +17 -3
- data/lib/rails/generators/mongoid/config/templates/mongoid.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +36 -62
- data/lib/rails/generators/mongoid/model/model_generator.rb +4 -0
- data/lib/rails/generators/mongoid_generator.rb +13 -0
- data/lib/rails/mongoid.rb +4 -29
- data/spec/config/mongoid.yml +0 -1
- data/spec/integration/active_job_spec.rb +32 -0
- data/spec/integration/app_spec.rb +72 -52
- data/spec/integration/associations/belongs_to_spec.rb +1 -0
- data/spec/integration/associations/embedded_dirty_spec.rb +1 -0
- data/spec/integration/associations/embedded_spec.rb +75 -6
- data/spec/integration/associations/embeds_many_spec.rb +1 -0
- data/spec/integration/associations/embeds_one_spec.rb +1 -0
- data/spec/integration/associations/foreign_key_spec.rb +1 -0
- data/spec/integration/associations/foreign_key_spec_models.rb +1 -0
- data/spec/integration/associations/has_and_belongs_to_many_spec.rb +1 -0
- data/spec/integration/associations/has_many_spec.rb +1 -0
- data/spec/integration/associations/has_one_spec.rb +1 -0
- data/spec/integration/associations/nested_attributes_assignment_spec.rb +1 -0
- data/spec/integration/associations/reverse_population_spec.rb +1 -0
- data/spec/integration/associations/reverse_population_spec_models.rb +1 -0
- data/spec/integration/associations/scope_option_spec.rb +1 -0
- data/spec/integration/atomic/modifiers_spec.rb +1 -0
- data/spec/integration/bson_regexp_raw_spec.rb +1 -0
- data/spec/integration/callbacks_models.rb +3 -2
- data/spec/integration/callbacks_spec.rb +2 -1
- data/spec/integration/contextual/empty_spec.rb +1 -0
- data/spec/integration/criteria/alias_query_spec.rb +25 -88
- data/spec/integration/criteria/date_field_spec.rb +1 -0
- data/spec/integration/criteria/default_scope_spec.rb +1 -0
- data/spec/integration/criteria/logical_spec.rb +10 -28
- data/spec/integration/criteria/range_spec.rb +1 -2
- data/spec/integration/criteria/raw_value_spec.rb +525 -0
- data/spec/integration/criteria/time_with_zone_spec.rb +1 -0
- data/spec/integration/discriminator_key_spec.rb +1 -0
- data/spec/integration/discriminator_value_spec.rb +1 -0
- data/spec/integration/document_spec.rb +1 -0
- data/spec/integration/dots_and_dollars_spec.rb +1 -0
- data/spec/integration/encryption_spec.rb +100 -0
- data/spec/integration/i18n_fallbacks_spec.rb +7 -33
- data/spec/integration/matcher_examples_spec.rb +1 -0
- data/spec/integration/matcher_operator_data/bits_all_clear.yml +0 -15
- data/spec/integration/matcher_operator_data/bits_all_set.yml +0 -15
- data/spec/integration/matcher_operator_data/bits_any_clear.yml +0 -15
- data/spec/integration/matcher_operator_data/bits_any_set.yml +0 -15
- data/spec/integration/matcher_operator_data/size.yml +0 -3
- data/spec/integration/matcher_operator_data/type.yml +0 -6
- data/spec/integration/matcher_operator_data/type_array.yml +0 -1
- data/spec/integration/matcher_operator_data/type_decimal.yml +0 -4
- data/spec/integration/matcher_operator_spec.rb +1 -0
- data/spec/integration/matcher_spec.rb +21 -66
- data/spec/integration/persistence/range_field_spec.rb +1 -0
- data/spec/integration/server_query_spec.rb +1 -0
- data/spec/integration/shardable_spec.rb +1 -0
- data/spec/integration/stringified_symbol_field_spec.rb +1 -0
- data/spec/lite_spec_helper.rb +36 -10
- data/spec/mongoid/association/accessors_spec.rb +11 -28
- data/spec/mongoid/association/auto_save_spec.rb +1 -0
- data/spec/mongoid/association/builders_spec.rb +1 -0
- data/spec/mongoid/association/constrainable_spec.rb +1 -0
- data/spec/mongoid/association/counter_cache_spec.rb +1 -0
- data/spec/mongoid/association/depending_spec.rb +1 -0
- data/spec/mongoid/association/eager_spec.rb +52 -24
- data/spec/mongoid/association/embedded/cyclic_spec.rb +1 -0
- data/spec/mongoid/association/embedded/dirty_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embedded_in/binding_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embedded_in/buildable_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embedded_in_spec.rb +19 -7
- data/spec/mongoid/association/embedded/embeds_many/binding_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many/buildable_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_many_models.rb +17 -2
- data/spec/mongoid/association/embedded/embeds_many_query_spec.rb +4 -7
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/binding_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/buildable_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one_dnl_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +6 -1
- data/spec/mongoid/association/embedded/embeds_one_query_spec.rb +2 -1
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +1 -0
- data/spec/mongoid/association/macros_spec.rb +1 -0
- data/spec/mongoid/association/nested/many_spec.rb +1 -0
- data/spec/mongoid/association/nested/one_spec.rb +1 -0
- data/spec/mongoid/association/options_spec.rb +1 -0
- data/spec/mongoid/association/polymorphic_spec.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to/binding_spec.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to/buildable_spec.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to/eager_spec.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +1 -4
- data/spec/mongoid/association/referenced/belongs_to_models.rb +1 -0
- data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +2 -1
- data/spec/mongoid/association/referenced/belongs_to_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/buildable_spec.rb +2 -1
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/eager_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_persistence_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +38 -31
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_models.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_query_spec.rb +2 -1
- data/spec/mongoid/association/referenced/has_and_belongs_to_many_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/buildable_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/eager_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/proxy_query_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +1085 -2002
- data/spec/mongoid/association/referenced/has_many_models.rb +1 -0
- data/spec/mongoid/association/referenced/has_many_query_spec.rb +2 -1
- data/spec/mongoid/association/referenced/has_many_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_one/binding_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_one/buildable_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_one/eager_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_one/proxy_spec.rb +1 -0
- data/spec/mongoid/association/referenced/has_one_models.rb +1 -0
- data/spec/mongoid/association/referenced/has_one_query_spec.rb +2 -1
- data/spec/mongoid/association/referenced/has_one_spec.rb +1 -0
- data/spec/mongoid/association/reflections_spec.rb +1 -0
- data/spec/mongoid/association/syncable_spec.rb +1 -0
- data/spec/mongoid/association_spec.rb +1 -60
- data/spec/mongoid/atomic/modifiers_spec.rb +1 -0
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +1 -0
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +1 -0
- data/spec/mongoid/atomic/paths/root_spec.rb +1 -0
- data/spec/mongoid/atomic/paths_spec.rb +1 -0
- data/spec/mongoid/atomic_spec.rb +1 -0
- data/spec/mongoid/atomic_update_preparer_spec.rb +83 -0
- data/spec/mongoid/attributes/dynamic_spec.rb +1 -0
- data/spec/mongoid/attributes/embedded_spec.rb +118 -0
- data/spec/mongoid/attributes/nested_spec.rb +1 -0
- data/spec/mongoid/attributes/nested_spec_models.rb +1 -0
- data/spec/mongoid/attributes/projector_spec.rb +1 -0
- data/spec/mongoid/attributes/readonly_spec.rb +1 -19
- data/spec/mongoid/attributes_spec.rb +18 -35
- data/spec/mongoid/cacheable_spec.rb +1 -0
- data/spec/mongoid/changeable_spec.rb +4 -3
- data/spec/mongoid/clients/factory_spec.rb +77 -0
- data/spec/mongoid/clients/options_spec.rb +9 -5
- data/spec/mongoid/clients/sessions_spec.rb +27 -10
- data/spec/mongoid/clients/transactions_spec.rb +958 -185
- data/spec/mongoid/clients/transactions_spec_models.rb +159 -0
- data/spec/mongoid/clients_spec.rb +47 -2
- data/spec/mongoid/collection_configurable_spec.rb +1 -0
- data/spec/mongoid/composable_spec.rb +1 -0
- data/spec/mongoid/config/defaults_spec.rb +31 -92
- data/spec/mongoid/config/encryption_spec.rb +152 -0
- data/spec/mongoid/config/environment_spec.rb +13 -41
- data/spec/mongoid/config/introspection_spec.rb +114 -0
- data/spec/mongoid/config/options_spec.rb +1 -0
- data/spec/mongoid/config_spec.rb +20 -133
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +1 -0
- data/spec/mongoid/contextual/aggregable/memory_table_spec.rb +1 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +5 -29
- data/spec/mongoid/contextual/aggregable/none_spec.rb +3 -14
- data/spec/mongoid/contextual/atomic_spec.rb +203 -12
- data/spec/mongoid/contextual/map_reduce_spec.rb +1 -0
- data/spec/mongoid/contextual/memory_spec.rb +364 -534
- data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +10 -3
- data/spec/mongoid/contextual/mongo_spec.rb +101 -277
- data/spec/mongoid/contextual/none_spec.rb +1 -0
- data/spec/mongoid/copyable_spec.rb +1 -0
- data/spec/mongoid/copyable_spec_models.rb +1 -0
- data/spec/mongoid/criteria/findable_spec.rb +191 -0
- data/spec/mongoid/criteria/includable_spec.rb +1 -0
- data/spec/mongoid/criteria/includable_spec_models.rb +1 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +1 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +3 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +1 -0
- data/spec/mongoid/criteria/options_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +8 -7
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +21 -11
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/numeric_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -11
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +1 -11
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +48 -66
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +5 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +4 -3
- data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +1 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +51 -214
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +96 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +1 -0
- data/spec/mongoid/criteria/queryable/storable_spec.rb +10 -32
- data/spec/mongoid/criteria/scopable_spec.rb +1 -0
- data/spec/mongoid/criteria/translator_spec.rb +1 -0
- data/spec/mongoid/criteria_projection_spec.rb +6 -5
- data/spec/mongoid/criteria_spec.rb +221 -359
- data/spec/mongoid/document_fields_spec.rb +1 -0
- data/spec/mongoid/document_persistence_context_spec.rb +77 -0
- data/spec/mongoid/document_query_spec.rb +5 -4
- data/spec/mongoid/document_spec.rb +3 -148
- data/spec/mongoid/equality_spec.rb +41 -149
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +1 -0
- data/spec/mongoid/errors/attribute_not_loaded_spec.rb +32 -0
- data/spec/mongoid/errors/callback_spec.rb +1 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +1 -0
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +1 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_collection_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_config_file_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_config_option_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_field_option_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_field_type_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_includes_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_index_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_options_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_path_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_relation_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_scope_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +1 -0
- data/spec/mongoid/errors/invalid_time_spec.rb +1 -0
- data/spec/mongoid/errors/inverse_not_found_spec.rb +1 -0
- data/spec/mongoid/errors/mixed_client_configuration_spec.rb +1 -0
- data/spec/mongoid/errors/mixed_relations_spec.rb +1 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +9 -22
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +1 -0
- data/spec/mongoid/errors/no_client_config_spec.rb +1 -0
- data/spec/mongoid/errors/no_client_database_spec.rb +1 -0
- data/spec/mongoid/errors/no_client_hosts_spec.rb +1 -0
- data/spec/mongoid/errors/no_clients_config_spec.rb +1 -0
- data/spec/mongoid/errors/no_environment_spec.rb +1 -0
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +1 -0
- data/spec/mongoid/errors/no_metadata_spec.rb +1 -0
- data/spec/mongoid/errors/no_parent_spec.rb +1 -0
- data/spec/mongoid/errors/readonly_attribute_spec.rb +1 -0
- data/spec/mongoid/errors/readonly_document_spec.rb +1 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +1 -0
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +1 -0
- data/spec/mongoid/errors/unknown_attribute_spec.rb +1 -0
- data/spec/mongoid/errors/unsaved_document_spec.rb +1 -0
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +1 -0
- data/spec/mongoid/errors/validations_spec.rb +1 -0
- data/spec/mongoid/extensions/array_spec.rb +3 -262
- data/spec/mongoid/extensions/big_decimal_spec.rb +5 -4
- data/spec/mongoid/extensions/binary_spec.rb +1 -0
- data/spec/mongoid/extensions/boolean_spec.rb +1 -0
- data/spec/mongoid/extensions/date_class_mongoize_spec.rb +8 -7
- data/spec/mongoid/extensions/date_spec.rb +3 -20
- data/spec/mongoid/extensions/date_time_spec.rb +3 -9
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -0
- data/spec/mongoid/extensions/false_class_spec.rb +1 -7
- data/spec/mongoid/extensions/float_spec.rb +3 -9
- data/spec/mongoid/extensions/hash_spec.rb +19 -222
- data/spec/mongoid/extensions/integer_spec.rb +3 -8
- data/spec/mongoid/extensions/module_spec.rb +1 -0
- data/spec/mongoid/extensions/nil_class_spec.rb +1 -0
- data/spec/mongoid/extensions/object_id_spec.rb +1 -0
- data/spec/mongoid/extensions/object_spec.rb +1 -176
- data/spec/mongoid/extensions/range_spec.rb +1 -11
- data/spec/mongoid/extensions/raw_value_spec.rb +67 -0
- data/spec/mongoid/extensions/regexp_spec.rb +1 -0
- data/spec/mongoid/extensions/set_spec.rb +2 -3
- data/spec/mongoid/extensions/string_spec.rb +3 -113
- data/spec/mongoid/extensions/stringified_symbol_spec.rb +1 -0
- data/spec/mongoid/extensions/symbol_spec.rb +1 -31
- data/spec/mongoid/extensions/time_spec.rb +32 -350
- data/spec/mongoid/extensions/time_with_zone_spec.rb +17 -30
- data/spec/mongoid/extensions/true_class_spec.rb +1 -7
- data/spec/mongoid/factory_spec.rb +1 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +282 -119
- data/spec/mongoid/fields/localized_spec.rb +1 -0
- data/spec/mongoid/fields/standard_spec.rb +1 -0
- data/spec/mongoid/fields_spec.rb +60 -66
- data/spec/mongoid/findable_spec.rb +2 -61
- data/spec/mongoid/indexable/specification_spec.rb +132 -13
- data/spec/mongoid/indexable_spec.rb +323 -9
- data/spec/mongoid/inspectable_spec.rb +81 -0
- data/spec/mongoid/interceptable_spec.rb +3 -82
- data/spec/mongoid/interceptable_spec_models.rb +112 -47
- data/spec/mongoid/loading_spec.rb +110 -0
- data/spec/mongoid/loggable_spec.rb +1 -0
- data/spec/mongoid/matcher/extract_attribute_spec.rb +1 -0
- data/spec/mongoid/mongoizable_spec.rb +1 -0
- data/spec/mongoid/monkey_patches_spec.rb +211 -0
- data/spec/mongoid/persistable/creatable_spec.rb +1 -0
- data/spec/mongoid/persistable/deletable_spec.rb +78 -31
- data/spec/mongoid/persistable/destroyable_spec.rb +230 -52
- data/spec/mongoid/persistable/incrementable_spec.rb +1 -0
- data/spec/mongoid/persistable/logical_spec.rb +1 -0
- data/spec/mongoid/persistable/maxable_spec.rb +147 -0
- data/spec/mongoid/persistable/minable_spec.rb +147 -0
- data/spec/mongoid/persistable/multipliable_spec.rb +227 -0
- data/spec/mongoid/persistable/poppable_spec.rb +1 -0
- data/spec/mongoid/persistable/pullable_spec.rb +1 -0
- data/spec/mongoid/persistable/pushable_spec.rb +1 -0
- data/spec/mongoid/persistable/renamable_spec.rb +1 -0
- data/spec/mongoid/persistable/savable_spec.rb +2 -6
- data/spec/mongoid/persistable/settable_spec.rb +5 -4
- data/spec/mongoid/persistable/unsettable_spec.rb +1 -0
- data/spec/mongoid/persistable/updatable_spec.rb +3 -2
- data/spec/mongoid/persistable/upsertable_spec.rb +34 -1
- data/spec/mongoid/persistable_spec.rb +1 -0
- data/spec/mongoid/persistence_context_spec.rb +1 -0
- data/spec/mongoid/positional_spec.rb +1 -0
- data/spec/mongoid/railties/bson_object_id_serializer_spec.rb +24 -0
- data/spec/mongoid/railties/console_sandbox_spec.rb +44 -0
- data/spec/mongoid/relations/proxy_spec.rb +1 -0
- data/spec/mongoid/reloadable_spec.rb +28 -83
- data/spec/mongoid/scopable_spec.rb +39 -50
- data/spec/mongoid/search_indexable_spec.rb +147 -0
- data/spec/mongoid/selectable_spec.rb +1 -0
- data/spec/mongoid/serializable_spec.rb +10 -16
- data/spec/mongoid/shardable_models.rb +1 -0
- data/spec/mongoid/shardable_spec.rb +1 -0
- data/spec/mongoid/stateful_spec.rb +1 -0
- data/spec/mongoid/tasks/database_rake_spec.rb +127 -49
- data/spec/mongoid/tasks/database_spec.rb +48 -1
- data/spec/mongoid/tasks/encryption_spec.rb +187 -0
- data/spec/mongoid/threaded_spec.rb +38 -0
- data/spec/mongoid/timestamps/created/short_spec.rb +1 -0
- data/spec/mongoid/timestamps/created_spec.rb +1 -23
- data/spec/mongoid/timestamps/timeless_spec.rb +1 -0
- data/spec/mongoid/timestamps/updated/short_spec.rb +1 -0
- data/spec/mongoid/timestamps/updated_spec.rb +1 -0
- data/spec/mongoid/timestamps_spec.rb +1 -0
- data/spec/mongoid/timestamps_spec_models.rb +1 -0
- data/spec/mongoid/touchable_spec.rb +490 -62
- data/spec/mongoid/touchable_spec_models.rb +96 -1
- data/spec/mongoid/traversable_spec.rb +1 -0
- data/spec/mongoid/validatable/associated_spec.rb +5 -14
- data/spec/mongoid/validatable/format_spec.rb +1 -0
- data/spec/mongoid/validatable/length_spec.rb +1 -0
- data/spec/mongoid/validatable/numericality_spec.rb +1 -0
- data/spec/mongoid/validatable/presence_spec.rb +1 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +48 -3
- data/spec/mongoid/validatable_spec.rb +1 -0
- data/spec/mongoid/warnings_spec.rb +1 -0
- data/spec/mongoid_spec.rb +27 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +1 -0
- data/spec/rails/mongoid_spec.rb +26 -117
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/cluster_config.rb +231 -0
- data/spec/shared/lib/mrss/constraints.rb +378 -0
- data/spec/shared/lib/mrss/docker_runner.rb +298 -0
- data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
- data/spec/shared/lib/mrss/event_subscriber.rb +210 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +238 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +113 -0
- data/spec/shared/lib/mrss/session_registry.rb +69 -0
- data/spec/shared/lib/mrss/session_registry_legacy.rb +60 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +179 -0
- data/spec/shared/lib/mrss/utils.rb +37 -0
- data/spec/shared/share/Dockerfile.erb +281 -0
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/config.sh +27 -0
- data/spec/shared/shlib/distro.sh +74 -0
- data/spec/shared/shlib/server.sh +417 -0
- data/spec/shared/shlib/set_env.sh +146 -0
- data/spec/spec_helper.rb +26 -28
- data/spec/support/authorization.rb +1 -0
- data/spec/support/client_registry.rb +1 -0
- data/spec/support/constraints.rb +1 -0
- data/spec/support/crypt/models.rb +50 -0
- data/spec/support/crypt.rb +80 -0
- data/spec/support/expectations.rb +1 -0
- data/spec/support/feature_sandbox.rb +72 -0
- data/spec/support/helpers.rb +1 -0
- data/spec/support/immutable_ids.rb +22 -21
- data/spec/support/macros.rb +4 -6
- data/spec/support/models/account.rb +1 -0
- data/spec/support/models/acolyte.rb +1 -0
- data/spec/support/models/actor.rb +1 -0
- data/spec/support/models/actress.rb +1 -0
- data/spec/support/models/address.rb +3 -0
- data/spec/support/models/address_component.rb +1 -0
- data/spec/support/models/address_number.rb +1 -0
- data/spec/support/models/agency.rb +1 -0
- data/spec/support/models/agent.rb +1 -0
- data/spec/support/models/album.rb +1 -0
- data/spec/support/models/alert.rb +1 -0
- data/spec/support/models/animal.rb +1 -0
- data/spec/support/models/answer.rb +1 -0
- data/spec/support/models/appointment.rb +1 -0
- data/spec/support/models/armrest.rb +1 -0
- data/spec/support/models/array_field.rb +1 -0
- data/spec/support/models/article.rb +1 -0
- data/spec/support/models/artist.rb +1 -0
- data/spec/support/models/artwork.rb +1 -0
- data/spec/support/models/audible_sound.rb +1 -0
- data/spec/support/models/audio.rb +1 -0
- data/spec/support/models/augmentation.rb +1 -0
- data/spec/support/models/author.rb +1 -0
- data/spec/support/models/baby.rb +1 -0
- data/spec/support/models/band.rb +5 -1
- data/spec/support/models/bar.rb +1 -0
- data/spec/support/models/basic.rb +1 -0
- data/spec/support/models/bed.rb +1 -0
- data/spec/support/models/big_palette.rb +1 -0
- data/spec/support/models/birthday.rb +1 -0
- data/spec/support/models/bolt.rb +1 -0
- data/spec/support/models/bomb.rb +1 -0
- data/spec/support/models/book.rb +1 -0
- data/spec/support/models/breed.rb +1 -0
- data/spec/support/models/browser.rb +1 -0
- data/spec/support/models/building.rb +1 -0
- data/spec/support/models/building_address.rb +1 -0
- data/spec/support/models/bus.rb +1 -0
- data/spec/support/models/business.rb +1 -0
- data/spec/support/models/callback_test.rb +1 -0
- data/spec/support/models/canvas.rb +1 -0
- data/spec/support/models/car.rb +1 -0
- data/spec/support/models/cat.rb +1 -0
- data/spec/support/models/catalog.rb +1 -0
- data/spec/support/models/category.rb +1 -0
- data/spec/support/models/child.rb +1 -0
- data/spec/support/models/child_doc.rb +1 -0
- data/spec/support/models/church.rb +1 -0
- data/spec/support/models/circle.rb +1 -0
- data/spec/support/models/circuit.rb +1 -0
- data/spec/support/models/circus.rb +1 -0
- data/spec/support/models/code.rb +1 -0
- data/spec/support/models/coding/pull_request.rb +1 -0
- data/spec/support/models/coding.rb +1 -0
- data/spec/support/models/comment.rb +1 -0
- data/spec/support/models/company.rb +1 -0
- data/spec/support/models/consumption_period.rb +1 -0
- data/spec/support/models/contextable_item.rb +1 -0
- data/spec/support/models/contractor.rb +1 -0
- data/spec/support/models/cookie.rb +1 -0
- data/spec/support/models/country_code.rb +1 -0
- data/spec/support/models/courier_job.rb +1 -0
- data/spec/support/models/cover.rb +1 -0
- data/spec/support/models/crate.rb +1 -0
- data/spec/support/models/customer.rb +1 -0
- data/spec/support/models/customer_address.rb +1 -0
- data/spec/support/models/deed.rb +1 -0
- data/spec/support/models/definition.rb +1 -0
- data/spec/support/models/delegating_patient.rb +1 -0
- data/spec/support/models/description.rb +1 -0
- data/spec/support/models/dictionary.rb +1 -0
- data/spec/support/models/division.rb +1 -0
- data/spec/support/models/doctor.rb +1 -0
- data/spec/support/models/dog.rb +1 -0
- data/spec/support/models/dokument.rb +1 -0
- data/spec/support/models/draft.rb +1 -0
- data/spec/support/models/dragon.rb +1 -0
- data/spec/support/models/driver.rb +1 -0
- data/spec/support/models/drug.rb +1 -0
- data/spec/support/models/dungeon.rb +1 -0
- data/spec/support/models/edit.rb +1 -0
- data/spec/support/models/email.rb +1 -0
- data/spec/support/models/employer.rb +1 -0
- data/spec/support/models/entry.rb +1 -0
- data/spec/support/models/eraser.rb +1 -0
- data/spec/support/models/even.rb +1 -0
- data/spec/support/models/event.rb +1 -0
- data/spec/support/models/exhibition.rb +1 -0
- data/spec/support/models/exhibitor.rb +1 -0
- data/spec/support/models/explosion.rb +1 -0
- data/spec/support/models/eye.rb +1 -0
- data/spec/support/models/eye_bowl.rb +1 -0
- data/spec/support/models/face.rb +1 -0
- data/spec/support/models/fanatic.rb +1 -0
- data/spec/support/models/favorite.rb +8 -1
- data/spec/support/models/filesystem.rb +1 -0
- data/spec/support/models/fire_hydrant.rb +1 -0
- data/spec/support/models/firefox.rb +1 -0
- data/spec/support/models/fish.rb +1 -0
- data/spec/support/models/folder.rb +1 -0
- data/spec/support/models/folder_item.rb +1 -0
- data/spec/support/models/fruits.rb +1 -0
- data/spec/support/models/game.rb +1 -0
- data/spec/support/models/ghost.rb +1 -0
- data/spec/support/models/guitar.rb +1 -0
- data/spec/support/models/hole.rb +1 -0
- data/spec/support/models/home.rb +1 -0
- data/spec/support/models/house.rb +1 -0
- data/spec/support/models/html_writer.rb +1 -0
- data/spec/support/models/id_key.rb +1 -0
- data/spec/support/models/idnodef.rb +1 -0
- data/spec/support/models/image.rb +1 -0
- data/spec/support/models/implant.rb +1 -0
- data/spec/support/models/instrument.rb +1 -0
- data/spec/support/models/item.rb +1 -0
- data/spec/support/models/jar.rb +1 -0
- data/spec/support/models/kaleidoscope.rb +1 -0
- data/spec/support/models/kangaroo.rb +1 -0
- data/spec/support/models/label.rb +1 -0
- data/spec/support/models/language.rb +1 -0
- data/spec/support/models/lat_lng.rb +1 -6
- data/spec/support/models/league.rb +1 -0
- data/spec/support/models/learner.rb +1 -0
- data/spec/support/models/line_item.rb +1 -0
- data/spec/support/models/location.rb +1 -0
- data/spec/support/models/login.rb +1 -0
- data/spec/support/models/manufacturer.rb +1 -0
- data/spec/support/models/meat.rb +1 -0
- data/spec/support/models/membership.rb +1 -0
- data/spec/support/models/message.rb +1 -0
- data/spec/support/models/minim.rb +1 -0
- data/spec/support/models/mixed_drink.rb +1 -0
- data/spec/support/models/mop.rb +1 -0
- data/spec/support/models/movie.rb +1 -0
- data/spec/support/models/my_hash.rb +1 -0
- data/spec/support/models/name.rb +1 -0
- data/spec/support/models/name_only.rb +1 -0
- data/spec/support/models/node.rb +1 -0
- data/spec/support/models/note.rb +1 -0
- data/spec/support/models/nut.rb +1 -0
- data/spec/support/models/odd.rb +1 -0
- data/spec/support/models/order.rb +1 -0
- data/spec/support/models/ordered_post.rb +1 -0
- data/spec/support/models/ordered_preference.rb +1 -0
- data/spec/support/models/oscar.rb +1 -0
- data/spec/support/models/other_owner_object.rb +1 -0
- data/spec/support/models/override.rb +1 -0
- data/spec/support/models/ownable.rb +1 -0
- data/spec/support/models/owner.rb +1 -0
- data/spec/support/models/pack.rb +1 -0
- data/spec/support/models/page.rb +1 -0
- data/spec/support/models/page_question.rb +1 -0
- data/spec/support/models/palette.rb +1 -0
- data/spec/support/models/parent.rb +1 -0
- data/spec/support/models/parent_doc.rb +1 -0
- data/spec/support/models/passport.rb +1 -0
- data/spec/support/models/patient.rb +1 -0
- data/spec/support/models/pdf_writer.rb +1 -0
- data/spec/support/models/pencil.rb +1 -0
- data/spec/support/models/person.rb +1 -0
- data/spec/support/models/pet.rb +1 -0
- data/spec/support/models/pet_owner.rb +1 -0
- data/spec/support/models/phone.rb +1 -0
- data/spec/support/models/piano.rb +1 -0
- data/spec/support/models/pizza.rb +1 -0
- data/spec/support/models/player.rb +1 -0
- data/spec/support/models/post.rb +1 -0
- data/spec/support/models/post_genre.rb +1 -0
- data/spec/support/models/powerup.rb +1 -0
- data/spec/support/models/preference.rb +1 -0
- data/spec/support/models/princess.rb +1 -0
- data/spec/support/models/product.rb +1 -0
- data/spec/support/models/profile.rb +1 -0
- data/spec/support/models/pronunciation.rb +1 -0
- data/spec/support/models/pub.rb +1 -0
- data/spec/support/models/publication/encyclopedia.rb +1 -0
- data/spec/support/models/publication/review.rb +1 -0
- data/spec/support/models/publication.rb +1 -0
- data/spec/support/models/purchase.rb +1 -0
- data/spec/support/models/purchased_item.rb +1 -0
- data/spec/support/models/question.rb +1 -0
- data/spec/support/models/quiz.rb +1 -0
- data/spec/support/models/rating.rb +1 -0
- data/spec/support/models/record.rb +1 -0
- data/spec/support/models/registry.rb +1 -0
- data/spec/support/models/role.rb +1 -0
- data/spec/support/models/root_category.rb +1 -0
- data/spec/support/models/sandbox/app/models/app_models_message.rb +4 -0
- data/spec/support/models/sandbox/lib/models/lib_models_message.rb +4 -0
- data/spec/support/models/sandbox/sandbox_message.rb +4 -0
- data/spec/support/models/sandbox/sandbox_user.rb +4 -0
- data/spec/support/models/sandbox/subdir/sandbox_comment.rb +4 -0
- data/spec/support/models/sandwich.rb +1 -0
- data/spec/support/models/scheduler.rb +1 -0
- data/spec/support/models/school.rb +1 -0
- data/spec/support/models/scribe.rb +1 -0
- data/spec/support/models/sealer.rb +1 -0
- data/spec/support/models/seat.rb +1 -0
- data/spec/support/models/seo.rb +1 -0
- data/spec/support/models/series.rb +1 -0
- data/spec/support/models/server.rb +1 -0
- data/spec/support/models/service.rb +1 -0
- data/spec/support/models/shape.rb +1 -0
- data/spec/support/models/shelf.rb +1 -0
- data/spec/support/models/shield.rb +1 -0
- data/spec/support/models/shipment_address.rb +1 -0
- data/spec/support/models/shipping_container.rb +1 -0
- data/spec/support/models/shipping_pack.rb +1 -0
- data/spec/support/models/shirt.rb +1 -0
- data/spec/support/models/shop.rb +1 -0
- data/spec/support/models/short_agent.rb +1 -0
- data/spec/support/models/short_quiz.rb +1 -0
- data/spec/support/models/simple.rb +1 -0
- data/spec/support/models/slave.rb +1 -0
- data/spec/support/models/song.rb +1 -0
- data/spec/support/models/sound.rb +1 -0
- data/spec/support/models/spacer.rb +1 -0
- data/spec/support/models/square.rb +1 -0
- data/spec/support/models/staff.rb +1 -0
- data/spec/support/models/store_as_dup_test1.rb +1 -0
- data/spec/support/models/store_as_dup_test2.rb +1 -0
- data/spec/support/models/store_as_dup_test3.rb +1 -0
- data/spec/support/models/store_as_dup_test4.rb +1 -0
- data/spec/support/models/strategy.rb +1 -0
- data/spec/support/models/student.rb +1 -0
- data/spec/support/models/sub_item.rb +1 -0
- data/spec/support/models/subscription.rb +1 -0
- data/spec/support/models/survey.rb +1 -0
- data/spec/support/models/symptom.rb +1 -0
- data/spec/support/models/system_role.rb +1 -0
- data/spec/support/models/tag.rb +1 -0
- data/spec/support/models/target.rb +1 -0
- data/spec/support/models/template.rb +1 -0
- data/spec/support/models/thing.rb +1 -0
- data/spec/support/models/threadlocker.rb +1 -0
- data/spec/support/models/title.rb +1 -0
- data/spec/support/models/tool.rb +1 -0
- data/spec/support/models/topping.rb +1 -0
- data/spec/support/models/toy.rb +1 -0
- data/spec/support/models/track.rb +1 -0
- data/spec/support/models/translation.rb +1 -0
- data/spec/support/models/tree.rb +1 -0
- data/spec/support/models/truck.rb +1 -0
- data/spec/support/models/updatable.rb +1 -0
- data/spec/support/models/user.rb +1 -0
- data/spec/support/models/user_account.rb +1 -0
- data/spec/support/models/validation_callback.rb +1 -0
- data/spec/support/models/vehicle.rb +1 -0
- data/spec/support/models/version.rb +1 -0
- data/spec/support/models/vertex.rb +1 -0
- data/spec/support/models/vet_visit.rb +1 -0
- data/spec/support/models/video.rb +1 -0
- data/spec/support/models/video_game.rb +1 -0
- data/spec/support/models/washer.rb +1 -0
- data/spec/support/models/weapon.rb +1 -0
- data/spec/support/models/wiki_page.rb +1 -0
- data/spec/support/models/word.rb +1 -0
- data/spec/support/models/word_origin.rb +1 -0
- data/spec/support/models/writer.rb +1 -0
- data/spec/support/rails_mock.rb +32 -0
- data/spec/support/shared/time.rb +3 -21
- data/spec/support/sinatra_mock.rb +7 -0
- data/spec/support/spec_config.rb +30 -9
- data.tar.gz.sig +0 -0
- metadata +171 -37
- metadata.gz.sig +1 -0
- data/lib/mongoid/association/referenced/eager.rb +0 -163
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +0 -113
- data/lib/mongoid/contextual/geo_near.rb +0 -236
- data/lib/mongoid/errors/invalid_session_use.rb +0 -21
- data/lib/mongoid/errors/invalid_storage_parent.rb +0 -27
- data/lib/mongoid/query_cache.rb +0 -68
- data/spec/mongoid/contextual/geo_near_spec.rb +0 -471
- data/spec/mongoid/extensions_spec.rb +0 -43
- data/spec/mongoid/query_cache_middleware_spec.rb +0 -50
- data/spec/mongoid/query_cache_spec.rb +0 -865
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require 'spec_helper'
|
4
4
|
|
5
5
|
module RefHasManySpec
|
6
6
|
module OverrideInitialize
|
@@ -16,7 +16,7 @@ module RefHasManySpec
|
|
16
16
|
|
17
17
|
def initialize(*args)
|
18
18
|
super
|
19
|
-
self.name ||=
|
19
|
+
self.name ||= 'default'
|
20
20
|
end
|
21
21
|
end
|
22
22
|
end
|
@@ -35,197 +35,163 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
35
35
|
Person.has_many :drugs, validate: false
|
36
36
|
end
|
37
37
|
|
38
|
-
[
|
39
|
-
|
38
|
+
%i[ << push ].each do |method|
|
40
39
|
describe "##{method}" do
|
40
|
+
context 'when providing the base class in child constructor' do
|
41
|
+
let(:person) { Person.create! }
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
let(:person) do
|
45
|
-
Person.create!
|
46
|
-
end
|
47
|
-
|
48
|
-
let!(:post) do
|
49
|
-
person.posts.send(method, Post.new(person: person))
|
50
|
-
end
|
43
|
+
before { person.posts.send(method, Post.new(person: person)) }
|
51
44
|
|
52
|
-
it
|
45
|
+
it 'only adds the association once' do
|
53
46
|
expect(person.posts.size).to eq(1)
|
54
47
|
end
|
55
48
|
|
56
|
-
it
|
49
|
+
it 'only persists the association once' do
|
57
50
|
expect(person.reload.posts.size).to eq(1)
|
58
51
|
end
|
59
52
|
end
|
60
53
|
|
61
|
-
context
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
let(:person) do
|
66
|
-
Person.new
|
67
|
-
end
|
68
|
-
|
69
|
-
context "when the child is new" do
|
70
|
-
|
71
|
-
let(:post) do
|
72
|
-
Post.new
|
73
|
-
end
|
54
|
+
context 'when the associations are not polymorphic' do
|
55
|
+
context 'when the parent is a new record' do
|
56
|
+
let(:person) { Person.new }
|
74
57
|
|
75
|
-
|
76
|
-
|
77
|
-
|
58
|
+
context 'when the child is new' do
|
59
|
+
let(:post) { Post.new }
|
60
|
+
let!(:added) { person.posts.send(method, post) }
|
78
61
|
|
79
|
-
it
|
62
|
+
it 'sets the foreign key on the association' do
|
80
63
|
expect(post.person_id).to eq(person.id)
|
81
64
|
end
|
82
65
|
|
83
|
-
it
|
66
|
+
it 'sets the base on the inverse association' do
|
84
67
|
expect(post.person).to eq(person)
|
85
68
|
end
|
86
69
|
|
87
|
-
it
|
70
|
+
it 'sets the same instance on the inverse association' do
|
88
71
|
expect(post.person).to eql(person)
|
89
72
|
end
|
90
73
|
|
91
|
-
it
|
74
|
+
it 'does not save the target' do
|
92
75
|
expect(post).to be_new_record
|
93
76
|
end
|
94
77
|
|
95
|
-
it
|
78
|
+
it 'adds the document to the target' do
|
96
79
|
expect(person.posts.size).to eq(1)
|
97
80
|
end
|
98
81
|
|
99
|
-
it
|
82
|
+
it 'returns the association' do
|
100
83
|
expect(added).to eq(person.posts)
|
101
84
|
end
|
102
85
|
end
|
103
86
|
|
104
|
-
context
|
105
|
-
|
106
|
-
let(:post) do
|
107
|
-
Post.create!
|
108
|
-
end
|
87
|
+
context 'when the child is persisted' do
|
88
|
+
let(:post) { Post.create! }
|
109
89
|
|
110
90
|
before do
|
111
91
|
person.posts.send(method, post)
|
112
92
|
end
|
113
93
|
|
114
|
-
it
|
94
|
+
it 'sets the foreign key on the association' do
|
115
95
|
expect(post.person_id).to eq(person.id)
|
116
96
|
end
|
117
97
|
|
118
|
-
it
|
98
|
+
it 'sets the base on the inverse association' do
|
119
99
|
expect(post.person).to eq(person)
|
120
100
|
end
|
121
101
|
|
122
|
-
it
|
102
|
+
it 'sets the same instance on the inverse association' do
|
123
103
|
expect(post.person).to eql(person)
|
124
104
|
end
|
125
105
|
|
126
|
-
it
|
106
|
+
it 'does not save the parent' do
|
127
107
|
expect(person).to be_new_record
|
128
108
|
end
|
129
109
|
|
130
|
-
it
|
110
|
+
it 'adds the document to the target' do
|
131
111
|
expect(person.posts.size).to eq(1)
|
132
112
|
end
|
133
113
|
|
134
|
-
context
|
135
|
-
|
114
|
+
context 'when subsequently saving the parent' do
|
136
115
|
before do
|
137
116
|
person.save!
|
138
117
|
post.save!
|
139
118
|
end
|
140
119
|
|
141
|
-
it
|
120
|
+
it 'returns the correct count of the association' do
|
142
121
|
expect(person.posts.count).to eq(1)
|
143
122
|
end
|
144
123
|
end
|
145
124
|
end
|
146
125
|
end
|
147
126
|
|
148
|
-
context
|
149
|
-
|
150
|
-
let!(:post) do
|
151
|
-
Post.create!(title: "testing")
|
152
|
-
end
|
153
|
-
|
127
|
+
context 'when appending in a parent create block' do
|
128
|
+
let!(:post) { Post.create!(title: 'testing') }
|
154
129
|
let!(:person) do
|
155
130
|
Person.create! do |doc|
|
156
131
|
doc.posts << post
|
157
132
|
end
|
158
133
|
end
|
159
134
|
|
160
|
-
it
|
135
|
+
it 'adds the documents to the association' do
|
161
136
|
expect(person.posts).to eq([ post ])
|
162
137
|
end
|
163
138
|
|
164
|
-
it
|
139
|
+
it 'sets the foreign key on the inverse association' do
|
165
140
|
expect(post.person_id).to eq(person.id)
|
166
141
|
end
|
167
142
|
|
168
|
-
it
|
143
|
+
it 'saves the target' do
|
169
144
|
expect(post).to be_persisted
|
170
145
|
end
|
171
146
|
|
172
|
-
it
|
147
|
+
it 'adds the correct number of documents' do
|
173
148
|
expect(person.posts.size).to eq(1)
|
174
149
|
end
|
175
150
|
|
176
|
-
it
|
151
|
+
it 'persists the link' do
|
177
152
|
expect(person.reload.posts).to eq([ post ])
|
178
153
|
end
|
179
154
|
end
|
180
155
|
|
181
|
-
context
|
182
|
-
|
183
|
-
let(:
|
184
|
-
Person.create!
|
185
|
-
end
|
186
|
-
|
187
|
-
let(:post) do
|
188
|
-
Post.new
|
189
|
-
end
|
156
|
+
context 'when the parent is not a new record' do
|
157
|
+
let(:person) { Person.create! }
|
158
|
+
let(:post) { Post.new }
|
190
159
|
|
191
160
|
before do
|
192
161
|
person.posts.send(method, post)
|
193
162
|
end
|
194
163
|
|
195
|
-
it
|
164
|
+
it 'sets the foreign key on the association' do
|
196
165
|
expect(post.person_id).to eq(person.id)
|
197
166
|
end
|
198
167
|
|
199
|
-
it
|
168
|
+
it 'sets the base on the inverse association' do
|
200
169
|
expect(post.person).to eq(person)
|
201
170
|
end
|
202
171
|
|
203
|
-
it
|
172
|
+
it 'sets the same instance on the inverse association' do
|
204
173
|
expect(post.person).to eql(person)
|
205
174
|
end
|
206
175
|
|
207
|
-
it
|
176
|
+
it 'saves the target' do
|
208
177
|
expect(post).to be_persisted
|
209
178
|
end
|
210
179
|
|
211
|
-
it
|
180
|
+
it 'adds the document to the target' do
|
212
181
|
expect(person.posts.count).to eq(1)
|
213
182
|
end
|
214
183
|
|
215
|
-
it
|
184
|
+
it 'increments the counter cache' do
|
216
185
|
expect(person[:posts_count]).to eq(1)
|
217
186
|
expect(person.posts_count).to eq(1)
|
218
187
|
end
|
219
188
|
|
220
|
-
it
|
189
|
+
it 'doesnt change the list of changes' do
|
221
190
|
expect(person.changed).to eq([])
|
222
191
|
end
|
223
192
|
|
224
|
-
context
|
225
|
-
|
226
|
-
let!(:user) do
|
227
|
-
User.create!
|
228
|
-
end
|
193
|
+
context 'when the related item has embedded associations' do
|
194
|
+
let!(:user) { User.create! }
|
229
195
|
|
230
196
|
before do
|
231
197
|
p = Post.create!(roles: [ Role.create! ])
|
@@ -233,169 +199,137 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
233
199
|
user.save!
|
234
200
|
end
|
235
201
|
|
236
|
-
it
|
202
|
+
it 'add the document to the target' do
|
237
203
|
expect(user.posts.size).to eq(1)
|
238
204
|
expect(user.posts.first.roles.size).to eq(1)
|
239
205
|
end
|
240
206
|
end
|
241
207
|
|
242
|
-
context
|
243
|
-
|
208
|
+
context 'when saving another post' do
|
244
209
|
before do
|
245
210
|
person.posts.send(method, Post.new)
|
246
211
|
end
|
247
212
|
|
248
|
-
it
|
213
|
+
it 'increments the counter cache' do
|
249
214
|
expect(person.posts_count).to eq(2)
|
250
215
|
end
|
251
216
|
end
|
252
217
|
|
253
|
-
context
|
254
|
-
|
255
|
-
let(:post_two) do
|
256
|
-
Post.new(title: "Test")
|
257
|
-
end
|
218
|
+
context 'when documents already exist on the association' do
|
219
|
+
let(:post_two) { Post.new(title: 'Test') }
|
258
220
|
|
259
221
|
before do
|
260
222
|
person.posts.send(method, post_two)
|
261
223
|
end
|
262
224
|
|
263
|
-
it
|
225
|
+
it 'sets the foreign key on the association' do
|
264
226
|
expect(post_two.person_id).to eq(person.id)
|
265
227
|
end
|
266
228
|
|
267
|
-
it
|
229
|
+
it 'sets the base on the inverse association' do
|
268
230
|
expect(post_two.person).to eq(person)
|
269
231
|
end
|
270
232
|
|
271
|
-
it
|
233
|
+
it 'sets the same instance on the inverse association' do
|
272
234
|
expect(post_two.person).to eql(person)
|
273
235
|
end
|
274
236
|
|
275
|
-
it
|
237
|
+
it 'saves the target' do
|
276
238
|
expect(post_two).to be_persisted
|
277
239
|
end
|
278
240
|
|
279
|
-
it
|
241
|
+
it 'adds the document to the target' do
|
280
242
|
expect(person.posts.count).to eq(2)
|
281
243
|
end
|
282
244
|
|
283
|
-
it
|
245
|
+
it 'increments the counter cache' do
|
284
246
|
expect(person.reload.posts_count).to eq(2)
|
285
247
|
end
|
286
248
|
|
287
|
-
it
|
249
|
+
it 'contains the initial document in the target' do
|
288
250
|
expect(person.posts).to include(post)
|
289
251
|
end
|
290
252
|
|
291
|
-
it
|
253
|
+
it 'contains the added document in the target' do
|
292
254
|
expect(person.posts).to include(post_two)
|
293
255
|
end
|
294
256
|
end
|
295
257
|
end
|
296
258
|
end
|
297
259
|
|
298
|
-
context
|
299
|
-
|
300
|
-
let(:person) do
|
301
|
-
Person.create!
|
302
|
-
end
|
303
|
-
|
304
|
-
context "when the operation succeeds" do
|
260
|
+
context 'when.adding to the association' do
|
261
|
+
let(:person) { Person.create! }
|
305
262
|
|
306
|
-
|
307
|
-
|
308
|
-
end
|
263
|
+
context 'when the operation succeeds' do
|
264
|
+
let(:post) { Post.new }
|
309
265
|
|
310
266
|
before do
|
311
267
|
person.posts.send(method, post)
|
312
268
|
end
|
313
269
|
|
314
|
-
it
|
270
|
+
it 'adds the document to the association' do
|
315
271
|
expect(person.posts).to eq([ post ])
|
316
272
|
end
|
317
273
|
end
|
318
274
|
|
319
|
-
context
|
320
|
-
|
321
|
-
let
|
322
|
-
Post.create!
|
323
|
-
end
|
324
|
-
|
325
|
-
let(:post) do
|
326
|
-
Post.new do |doc|
|
327
|
-
doc._id = existing.id
|
328
|
-
end
|
329
|
-
end
|
275
|
+
context 'when the operation fails' do
|
276
|
+
let!(:existing) { Post.create! }
|
277
|
+
let(:post) { Post.new { |doc| doc._id = existing.id } }
|
330
278
|
|
331
|
-
it
|
332
|
-
expect {
|
333
|
-
|
334
|
-
}.to raise_error(Mongo::Error::OperationFailure)
|
279
|
+
it 'raises an error' do
|
280
|
+
expect { person.posts.send(method, post) }
|
281
|
+
.to raise_error(Mongo::Error::OperationFailure)
|
335
282
|
end
|
336
283
|
end
|
337
284
|
end
|
338
285
|
|
339
|
-
context
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
let(:movie) do
|
344
|
-
Movie.new
|
345
|
-
end
|
346
|
-
|
347
|
-
let(:rating) do
|
348
|
-
Rating.new
|
349
|
-
end
|
286
|
+
context 'when the associations are polymorphic' do
|
287
|
+
context 'when the parent is a new record' do
|
288
|
+
let(:movie) { Movie.new }
|
289
|
+
let(:rating) { Rating.new }
|
350
290
|
|
351
291
|
before do
|
352
292
|
movie.ratings.send(method, rating)
|
353
293
|
end
|
354
294
|
|
355
|
-
it
|
295
|
+
it 'sets the foreign key on the association' do
|
356
296
|
expect(rating.ratable_id).to eq(movie.id)
|
357
297
|
end
|
358
298
|
|
359
|
-
it
|
299
|
+
it 'sets the base on the inverse association' do
|
360
300
|
expect(rating.ratable).to eq(movie)
|
361
301
|
end
|
362
302
|
|
363
|
-
it
|
303
|
+
it 'does not save the target' do
|
364
304
|
expect(rating).to be_new_record
|
365
305
|
end
|
366
306
|
|
367
|
-
it
|
307
|
+
it 'adds the document to the target' do
|
368
308
|
expect(movie.ratings.size).to eq(1)
|
369
309
|
end
|
370
310
|
end
|
371
311
|
|
372
|
-
context
|
373
|
-
|
374
|
-
let(:
|
375
|
-
Movie.create!
|
376
|
-
end
|
377
|
-
|
378
|
-
let(:rating) do
|
379
|
-
Rating.new
|
380
|
-
end
|
312
|
+
context 'when the parent is not a new record' do
|
313
|
+
let(:movie) { Movie.create! }
|
314
|
+
let(:rating) { Rating.new }
|
381
315
|
|
382
316
|
before do
|
383
317
|
movie.ratings.send(method, rating)
|
384
318
|
end
|
385
319
|
|
386
|
-
it
|
320
|
+
it 'sets the foreign key on the association' do
|
387
321
|
expect(rating.ratable_id).to eq(movie.id)
|
388
322
|
end
|
389
323
|
|
390
|
-
it
|
324
|
+
it 'sets the base on the inverse association' do
|
391
325
|
expect(rating.ratable).to eq(movie)
|
392
326
|
end
|
393
327
|
|
394
|
-
it
|
328
|
+
it 'saves the target' do
|
395
329
|
expect(rating).to be_persisted
|
396
330
|
end
|
397
331
|
|
398
|
-
it
|
332
|
+
it 'adds the document to the target' do
|
399
333
|
expect(movie.ratings.count).to eq(1)
|
400
334
|
end
|
401
335
|
end
|
@@ -403,193 +337,160 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
403
337
|
end
|
404
338
|
end
|
405
339
|
|
406
|
-
describe
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
let(:person) do
|
413
|
-
Person.new
|
414
|
-
end
|
415
|
-
|
416
|
-
let(:post) do
|
417
|
-
Post.new
|
418
|
-
end
|
340
|
+
describe '#=' do
|
341
|
+
context 'when the association is not polymorphic' do
|
342
|
+
context 'when the parent is a new record' do
|
343
|
+
let(:person) { Person.new }
|
344
|
+
let(:post) { Post.new }
|
419
345
|
|
420
346
|
before do
|
421
347
|
person.posts = [ post ]
|
422
348
|
end
|
423
349
|
|
424
|
-
it
|
350
|
+
it 'sets the target of the association' do
|
425
351
|
expect(person.posts._target).to eq([ post ])
|
426
352
|
end
|
427
353
|
|
428
|
-
it
|
354
|
+
it 'sets the foreign key on the association' do
|
429
355
|
expect(post.person_id).to eq(person.id)
|
430
356
|
end
|
431
357
|
|
432
|
-
it
|
358
|
+
it 'sets the base on the inverse association' do
|
433
359
|
expect(post.person).to eq(person)
|
434
360
|
end
|
435
361
|
|
436
|
-
it
|
437
|
-
expect(post).
|
362
|
+
it 'does not save the target' do
|
363
|
+
expect(post).not_to be_persisted
|
438
364
|
end
|
439
365
|
end
|
440
366
|
|
441
|
-
context
|
442
|
-
|
443
|
-
let(:
|
444
|
-
Person.create!
|
445
|
-
end
|
446
|
-
|
447
|
-
let(:post) do
|
448
|
-
Post.new
|
449
|
-
end
|
367
|
+
context 'when the parent is not a new record' do
|
368
|
+
let(:person) { Person.create! }
|
369
|
+
let(:post) { Post.new }
|
450
370
|
|
451
371
|
before do
|
452
372
|
person.posts = [ post ]
|
453
373
|
end
|
454
374
|
|
455
|
-
it
|
375
|
+
it 'sets the target of the association' do
|
456
376
|
expect(person.posts._target).to eq([ post ])
|
457
377
|
end
|
458
378
|
|
459
|
-
it
|
379
|
+
it 'sets the foreign key of the association' do
|
460
380
|
expect(post.person_id).to eq(person.id)
|
461
381
|
end
|
462
382
|
|
463
|
-
it
|
383
|
+
it 'sets the base on the inverse association' do
|
464
384
|
expect(post.person).to eq(person)
|
465
385
|
end
|
466
386
|
|
467
|
-
it
|
387
|
+
it 'saves the target' do
|
468
388
|
expect(post).to be_persisted
|
469
389
|
end
|
470
390
|
|
471
|
-
context
|
472
|
-
|
473
|
-
context "when using the same in memory instance" do
|
474
|
-
|
391
|
+
context 'when replacing the association with the same documents' do
|
392
|
+
context 'when using the same in memory instance' do
|
475
393
|
before do
|
476
394
|
person.posts = [ post ]
|
477
395
|
end
|
478
396
|
|
479
|
-
it
|
397
|
+
it 'keeps the association intact' do
|
480
398
|
expect(person.posts).to eq([ post ])
|
481
399
|
end
|
482
400
|
|
483
|
-
it
|
401
|
+
it 'does not delete the association' do
|
484
402
|
expect(person.reload.posts).to eq([ post ])
|
485
403
|
end
|
486
404
|
end
|
487
405
|
|
488
|
-
context
|
489
|
-
|
490
|
-
let(:from_db) do
|
491
|
-
Person.find(person.id)
|
492
|
-
end
|
406
|
+
context 'when using a new instance' do
|
407
|
+
let(:from_db) { Person.find(person.id) }
|
493
408
|
|
494
409
|
before do
|
495
410
|
from_db.posts = [ post ]
|
496
411
|
end
|
497
412
|
|
498
|
-
it
|
413
|
+
it 'keeps the association intact' do
|
499
414
|
expect(from_db.posts).to eq([ post ])
|
500
415
|
end
|
501
416
|
|
502
|
-
it
|
417
|
+
it 'does not delete the association' do
|
503
418
|
expect(from_db.reload.posts).to eq([ post ])
|
504
419
|
end
|
505
420
|
end
|
506
421
|
end
|
507
422
|
|
508
|
-
context
|
509
|
-
|
510
|
-
let(:new_post) do
|
511
|
-
Post.create!(title: "new post")
|
512
|
-
end
|
513
|
-
|
514
|
-
context "when using the same in memory instance" do
|
423
|
+
context 'when replacing the with a combination of old and new docs' do
|
424
|
+
let(:new_post) { Post.create!(title: 'new post') }
|
515
425
|
|
426
|
+
context 'when using the same in memory instance' do
|
516
427
|
before do
|
517
428
|
person.posts = [ post, new_post ]
|
518
429
|
end
|
519
430
|
|
520
|
-
it
|
431
|
+
it 'keeps the association intact' do
|
521
432
|
expect(person.posts.size).to eq(2)
|
522
433
|
end
|
523
434
|
|
524
|
-
it
|
435
|
+
it 'keeps the first post' do
|
525
436
|
expect(person.posts).to include(post)
|
526
437
|
end
|
527
438
|
|
528
|
-
it
|
439
|
+
it 'keeps the second post' do
|
529
440
|
expect(person.posts).to include(new_post)
|
530
441
|
end
|
531
442
|
|
532
|
-
it
|
443
|
+
it 'does not delete the association' do
|
533
444
|
expect(person.reload.posts).to eq([ post, new_post ])
|
534
445
|
end
|
535
446
|
end
|
536
447
|
|
537
|
-
context
|
538
|
-
|
539
|
-
let(:from_db) do
|
540
|
-
Person.find(person.id)
|
541
|
-
end
|
448
|
+
context 'when using a new instance' do
|
449
|
+
let(:from_db) { Person.find(person.id) }
|
542
450
|
|
543
451
|
before do
|
544
452
|
from_db.posts = [ post, new_post ]
|
545
453
|
end
|
546
454
|
|
547
|
-
it
|
455
|
+
it 'keeps the association intact' do
|
548
456
|
expect(from_db.posts).to eq([ post, new_post ])
|
549
457
|
end
|
550
458
|
|
551
|
-
it
|
459
|
+
it 'does not delete the association' do
|
552
460
|
expect(from_db.reload.posts).to eq([ post, new_post ])
|
553
461
|
end
|
554
462
|
end
|
555
463
|
end
|
556
464
|
|
557
|
-
context
|
558
|
-
|
559
|
-
let(:new_post) do
|
560
|
-
Post.create!(title: "new post")
|
561
|
-
end
|
562
|
-
|
563
|
-
context "when using the same in memory instance" do
|
465
|
+
context 'when replacing the with a combination of only new docs' do
|
466
|
+
let(:new_post) { Post.create!(title: 'new post') }
|
564
467
|
|
468
|
+
context 'when using the same in memory instance' do
|
565
469
|
before do
|
566
470
|
person.posts = [ new_post ]
|
567
471
|
end
|
568
472
|
|
569
|
-
it
|
473
|
+
it 'keeps the association intact' do
|
570
474
|
expect(person.posts).to eq([ new_post ])
|
571
475
|
end
|
572
476
|
|
573
|
-
it
|
477
|
+
it 'does not delete the association' do
|
574
478
|
expect(person.reload.posts).to eq([ new_post ])
|
575
479
|
end
|
576
480
|
end
|
577
481
|
|
578
|
-
context
|
579
|
-
|
580
|
-
let(:from_db) do
|
581
|
-
Person.find(person.id)
|
582
|
-
end
|
482
|
+
context 'when using a new instance' do
|
483
|
+
let(:from_db) { Person.find(person.id) }
|
583
484
|
|
584
485
|
before do
|
585
486
|
from_db.posts = [ new_post ]
|
586
487
|
end
|
587
488
|
|
588
|
-
it
|
489
|
+
it 'keeps the association intact' do
|
589
490
|
expect(from_db.posts).to eq([ new_post ])
|
590
491
|
end
|
591
492
|
|
592
|
-
it
|
493
|
+
it 'does not delete the association' do
|
593
494
|
expect(from_db.reload.posts).to eq([ new_post ])
|
594
495
|
end
|
595
496
|
end
|
@@ -597,470 +498,371 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
597
498
|
end
|
598
499
|
end
|
599
500
|
|
600
|
-
context
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
let(:movie) do
|
605
|
-
Movie.new
|
606
|
-
end
|
607
|
-
|
608
|
-
let(:rating) do
|
609
|
-
Rating.new
|
610
|
-
end
|
501
|
+
context 'when the association is polymorphic' do
|
502
|
+
context 'when the parent is a new record' do
|
503
|
+
let(:movie) { Movie.new }
|
504
|
+
let(:rating) { Rating.new }
|
611
505
|
|
612
506
|
before do
|
613
507
|
movie.ratings = [ rating ]
|
614
508
|
end
|
615
509
|
|
616
|
-
it
|
510
|
+
it 'sets the target of the association' do
|
617
511
|
expect(movie.ratings._target).to eq([ rating ])
|
618
512
|
end
|
619
513
|
|
620
|
-
it
|
514
|
+
it 'sets the foreign key on the association' do
|
621
515
|
expect(rating.ratable_id).to eq(movie.id)
|
622
516
|
end
|
623
517
|
|
624
|
-
it
|
518
|
+
it 'sets the base on the inverse association' do
|
625
519
|
expect(rating.ratable).to eq(movie)
|
626
520
|
end
|
627
521
|
|
628
|
-
it
|
629
|
-
expect(rating).
|
522
|
+
it 'does not save the target' do
|
523
|
+
expect(rating).not_to be_persisted
|
630
524
|
end
|
631
525
|
end
|
632
526
|
|
633
|
-
context
|
634
|
-
|
635
|
-
let(:
|
636
|
-
Movie.create!
|
637
|
-
end
|
638
|
-
|
639
|
-
let(:rating) do
|
640
|
-
Rating.new
|
641
|
-
end
|
527
|
+
context 'when the parent is not a new record' do
|
528
|
+
let(:movie) { Movie.create! }
|
529
|
+
let(:rating) { Rating.new }
|
642
530
|
|
643
531
|
before do
|
644
532
|
movie.ratings = [ rating ]
|
645
533
|
end
|
646
534
|
|
647
|
-
it
|
535
|
+
it 'sets the target of the association' do
|
648
536
|
expect(movie.ratings._target).to eq([ rating ])
|
649
537
|
end
|
650
538
|
|
651
|
-
it
|
539
|
+
it 'sets the foreign key of the association' do
|
652
540
|
expect(rating.ratable_id).to eq(movie.id)
|
653
541
|
end
|
654
542
|
|
655
|
-
it
|
543
|
+
it 'sets the base on the inverse association' do
|
656
544
|
expect(rating.ratable).to eq(movie)
|
657
545
|
end
|
658
546
|
|
659
|
-
it
|
547
|
+
it 'saves the target' do
|
660
548
|
expect(rating).to be_persisted
|
661
549
|
end
|
662
550
|
end
|
663
551
|
end
|
664
552
|
end
|
665
553
|
|
666
|
-
describe
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
let(:posts) do
|
671
|
-
[ Post.create!(title: "1"), Post.create!(title: "2") ]
|
672
|
-
end
|
673
|
-
|
674
|
-
let(:person) do
|
675
|
-
Person.create!(posts: posts)
|
676
|
-
end
|
677
|
-
|
678
|
-
context "when the parent has multiple children" do
|
554
|
+
describe '#= []' do
|
555
|
+
context 'when the parent is persisted' do
|
556
|
+
let(:posts) { [ Post.create!(title: '1'), Post.create!(title: '2') ] }
|
557
|
+
let(:person) { Person.create!(posts: posts) }
|
679
558
|
|
559
|
+
context 'when the parent has multiple children' do
|
680
560
|
before do
|
681
561
|
person.posts = []
|
682
562
|
end
|
683
563
|
|
684
|
-
it
|
564
|
+
it 'removes all the children' do
|
685
565
|
expect(person.posts).to be_empty
|
686
566
|
end
|
687
567
|
|
688
|
-
it
|
568
|
+
it 'persists the changes' do
|
689
569
|
expect(person.posts(true)).to be_empty
|
690
570
|
end
|
691
571
|
end
|
692
572
|
end
|
693
573
|
end
|
694
574
|
|
695
|
-
describe
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
let(:person) do
|
702
|
-
Person.new
|
703
|
-
end
|
704
|
-
|
705
|
-
let(:post) do
|
706
|
-
Post.new
|
707
|
-
end
|
575
|
+
describe '#= nil' do
|
576
|
+
context 'when the association is not polymorphic' do
|
577
|
+
context 'when the parent is a new record' do
|
578
|
+
let(:person) { Person.new }
|
579
|
+
let(:post) { Post.new }
|
708
580
|
|
709
581
|
before do
|
710
582
|
person.posts = [ post ]
|
711
583
|
person.posts = nil
|
712
584
|
end
|
713
585
|
|
714
|
-
it
|
586
|
+
it 'sets the association to an empty array' do
|
715
587
|
expect(person.posts).to be_empty
|
716
588
|
end
|
717
589
|
|
718
|
-
it
|
590
|
+
it 'removed the inverse association' do
|
719
591
|
expect(post.person).to be_nil
|
720
592
|
end
|
721
593
|
|
722
|
-
it
|
594
|
+
it 'removes the foreign key value' do
|
723
595
|
expect(post.person_id).to be_nil
|
724
596
|
end
|
725
597
|
end
|
726
598
|
|
727
|
-
context
|
728
|
-
|
729
|
-
let(:person) do
|
730
|
-
Person.create!
|
731
|
-
end
|
732
|
-
|
733
|
-
context "when dependent is destructive" do
|
599
|
+
context 'when the parent is not a new record' do
|
600
|
+
let(:person) { Person.create! }
|
734
601
|
|
735
|
-
|
736
|
-
|
737
|
-
end
|
602
|
+
context 'when dependent is destructive' do
|
603
|
+
let(:post) { Post.new }
|
738
604
|
|
739
605
|
before do
|
740
606
|
person.posts = [ post ]
|
741
607
|
person.posts = nil
|
742
608
|
end
|
743
609
|
|
744
|
-
it
|
610
|
+
it 'sets the association to empty' do
|
745
611
|
expect(person.posts).to be_empty
|
746
612
|
end
|
747
613
|
|
748
|
-
it
|
614
|
+
it 'removed the inverse association' do
|
749
615
|
expect(post.person).to be_nil
|
750
616
|
end
|
751
617
|
|
752
|
-
it
|
618
|
+
it 'removes the foreign key value' do
|
753
619
|
expect(post.person_id).to be_nil
|
754
620
|
end
|
755
621
|
|
756
|
-
it
|
622
|
+
it 'deletes the target from the database' do
|
757
623
|
expect(post).to be_destroyed
|
758
624
|
end
|
759
625
|
end
|
760
626
|
|
761
|
-
context
|
762
|
-
|
763
|
-
let(:drug) do
|
764
|
-
Drug.new(name: "Oxycodone")
|
765
|
-
end
|
627
|
+
context 'when dependent is not destructive' do
|
628
|
+
let(:drug) { Drug.new(name: 'Oxycodone') }
|
766
629
|
|
767
630
|
before do
|
768
631
|
person.drugs = [ drug ]
|
769
632
|
person.drugs = nil
|
770
633
|
end
|
771
634
|
|
772
|
-
it
|
635
|
+
it 'sets the association to empty' do
|
773
636
|
expect(person.drugs).to be_empty
|
774
637
|
end
|
775
638
|
|
776
|
-
it
|
639
|
+
it 'removed the inverse association' do
|
777
640
|
expect(drug.person).to be_nil
|
778
641
|
end
|
779
642
|
|
780
|
-
it
|
643
|
+
it 'removes the foreign key value' do
|
781
644
|
expect(drug.person_id).to be_nil
|
782
645
|
end
|
783
646
|
|
784
|
-
it
|
785
|
-
expect(drug).
|
647
|
+
it 'nullifies the association' do
|
648
|
+
expect(drug).not_to be_destroyed
|
786
649
|
end
|
787
650
|
end
|
788
651
|
end
|
789
652
|
end
|
790
653
|
|
791
|
-
context
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
let(:movie) do
|
796
|
-
Movie.new
|
797
|
-
end
|
798
|
-
|
799
|
-
let(:rating) do
|
800
|
-
Rating.new
|
801
|
-
end
|
654
|
+
context 'when the association is polymorphic' do
|
655
|
+
context 'when the parent is a new record' do
|
656
|
+
let(:movie) { Movie.new }
|
657
|
+
let(:rating) { Rating.new }
|
802
658
|
|
803
659
|
before do
|
804
660
|
movie.ratings = [ rating ]
|
805
661
|
movie.ratings = nil
|
806
662
|
end
|
807
663
|
|
808
|
-
it
|
664
|
+
it 'sets the association to an empty array' do
|
809
665
|
expect(movie.ratings).to be_empty
|
810
666
|
end
|
811
667
|
|
812
|
-
it
|
668
|
+
it 'removed the inverse association' do
|
813
669
|
expect(rating.ratable).to be_nil
|
814
670
|
end
|
815
671
|
|
816
|
-
it
|
672
|
+
it 'removes the foreign key value' do
|
817
673
|
expect(rating.ratable_id).to be_nil
|
818
674
|
end
|
819
675
|
end
|
820
676
|
|
821
|
-
context
|
822
|
-
|
823
|
-
let(:
|
824
|
-
Movie.create!
|
825
|
-
end
|
826
|
-
|
827
|
-
let(:rating) do
|
828
|
-
Rating.new
|
829
|
-
end
|
677
|
+
context 'when the parent is not a new record' do
|
678
|
+
let(:movie) { Movie.create! }
|
679
|
+
let(:rating) { Rating.new }
|
830
680
|
|
831
681
|
before do
|
832
682
|
movie.ratings = [ rating ]
|
833
683
|
movie.ratings = nil
|
834
684
|
end
|
835
685
|
|
836
|
-
it
|
686
|
+
it 'sets the association to empty' do
|
837
687
|
expect(movie.ratings).to be_empty
|
838
688
|
end
|
839
689
|
|
840
|
-
it
|
690
|
+
it 'removed the inverse association' do
|
841
691
|
expect(rating.ratable).to be_nil
|
842
692
|
end
|
843
693
|
|
844
|
-
it
|
694
|
+
it 'removes the foreign key value' do
|
845
695
|
expect(rating.ratable_id).to be_nil
|
846
696
|
end
|
847
697
|
|
848
|
-
context
|
849
|
-
|
850
|
-
|
851
|
-
expect(rating).to_not be_destroyed
|
698
|
+
context 'when dependent is nullify' do
|
699
|
+
it 'does not delete the target from the database' do
|
700
|
+
expect(rating).not_to be_destroyed
|
852
701
|
end
|
853
702
|
end
|
854
703
|
end
|
855
704
|
end
|
856
705
|
end
|
857
706
|
|
858
|
-
describe
|
859
|
-
|
860
|
-
let(:
|
861
|
-
Person.new
|
862
|
-
end
|
863
|
-
|
864
|
-
let(:post_one) do
|
865
|
-
Post.create!
|
866
|
-
end
|
707
|
+
describe '#\{name}_ids=' do
|
708
|
+
let(:person) { Person.new }
|
709
|
+
let(:post_one) { Post.create! }
|
867
710
|
|
868
|
-
let(:post_two)
|
869
|
-
Post.create!
|
870
|
-
end
|
711
|
+
let(:post_two) { Post.create! }
|
871
712
|
|
872
713
|
before do
|
873
714
|
person.post_ids = [ post_one.id, post_two.id ]
|
874
715
|
end
|
875
716
|
|
876
|
-
it
|
717
|
+
it 'calls setter with documents find by given ids' do
|
877
718
|
expect(person.posts).to eq([ post_one, post_two ])
|
878
719
|
end
|
879
720
|
end
|
880
721
|
|
881
|
-
describe
|
882
|
-
|
883
|
-
let(:posts)
|
884
|
-
[ Post.create!, Post.create! ]
|
885
|
-
end
|
886
|
-
|
887
|
-
let(:person) do
|
888
|
-
Person.create!(posts: posts)
|
889
|
-
end
|
722
|
+
describe '#\{name}_ids' do
|
723
|
+
let(:posts) { [ Post.create!, Post.create! ] }
|
724
|
+
let(:person) { Person.create!(posts: posts) }
|
890
725
|
|
891
|
-
it
|
726
|
+
it 'returns ids of documents that are in the association' do
|
892
727
|
expect(person.post_ids).to eq(posts.map(&:id))
|
893
728
|
end
|
894
729
|
end
|
895
730
|
|
896
|
-
[
|
897
|
-
|
731
|
+
%i[ build new ].each do |method|
|
898
732
|
describe "##{method}" do
|
899
733
|
context 'when model has #initialize' do
|
900
734
|
let(:parent) { RefHasManySpec::OverrideInitialize::Parent.create }
|
901
735
|
let(:child) { parent.children.send(method) }
|
902
736
|
|
903
|
-
it '
|
904
|
-
expect(child.name).to be ==
|
737
|
+
it 'calls #initialize' do
|
738
|
+
expect(child.name).to be == 'default'
|
905
739
|
end
|
906
740
|
end
|
907
741
|
|
908
|
-
context
|
909
|
-
|
910
|
-
|
742
|
+
context 'when the association is not polymorphic' do
|
743
|
+
context 'when the parent is a new record' do
|
744
|
+
let(:person) { Person.new(title: 'sir') }
|
745
|
+
let!(:post) { person.posts.send(method, title: '$$$') }
|
911
746
|
|
912
|
-
|
913
|
-
Person.new(title: "sir")
|
914
|
-
end
|
915
|
-
|
916
|
-
let!(:post) do
|
917
|
-
person.posts.send(method, title: "$$$")
|
918
|
-
end
|
919
|
-
|
920
|
-
it "sets the foreign key on the association" do
|
747
|
+
it 'sets the foreign key on the association' do
|
921
748
|
expect(post.person_id).to eq(person.id)
|
922
749
|
end
|
923
750
|
|
924
|
-
it
|
751
|
+
it 'sets the base on the inverse association' do
|
925
752
|
expect(post.person).to eq(person)
|
926
753
|
end
|
927
754
|
|
928
|
-
it
|
929
|
-
expect(post.title).to eq(
|
755
|
+
it 'sets the attributes' do
|
756
|
+
expect(post.title).to eq('$$$')
|
930
757
|
end
|
931
758
|
|
932
|
-
it
|
759
|
+
it 'sets the post processed defaults' do
|
933
760
|
expect(post.person_title).to eq(person.title)
|
934
761
|
end
|
935
762
|
|
936
|
-
it
|
763
|
+
it 'does not save the target' do
|
937
764
|
expect(post).to be_new_record
|
938
765
|
end
|
939
766
|
|
940
|
-
it
|
767
|
+
it 'adds the document to the target' do
|
941
768
|
expect(person.posts.size).to eq(1)
|
942
769
|
end
|
943
770
|
|
944
|
-
it
|
771
|
+
it 'does not perform validation' do
|
945
772
|
expect(post.errors).to be_empty
|
946
773
|
end
|
947
774
|
end
|
948
775
|
|
949
|
-
context
|
950
|
-
|
951
|
-
let(:person)
|
952
|
-
Person.create!
|
953
|
-
end
|
954
|
-
|
955
|
-
let!(:post) do
|
956
|
-
person.posts.send(method, text: "Testing")
|
957
|
-
end
|
776
|
+
context 'when the parent is not a new record' do
|
777
|
+
let(:person) { Person.create! }
|
778
|
+
let!(:post) { person.posts.send(method, text: 'Testing') }
|
958
779
|
|
959
|
-
it
|
780
|
+
it 'sets the foreign key on the association' do
|
960
781
|
expect(post.person_id).to eq(person.id)
|
961
782
|
end
|
962
783
|
|
963
|
-
it
|
784
|
+
it 'sets the base on the inverse association' do
|
964
785
|
expect(post.person).to eq(person)
|
965
786
|
end
|
966
787
|
|
967
|
-
it
|
968
|
-
expect(post.text).to eq(
|
788
|
+
it 'sets the attributes' do
|
789
|
+
expect(post.text).to eq('Testing')
|
969
790
|
end
|
970
791
|
|
971
|
-
it
|
792
|
+
it 'does not save the target' do
|
972
793
|
expect(post).to be_new_record
|
973
794
|
end
|
974
795
|
|
975
|
-
it
|
796
|
+
it 'adds the document to the target' do
|
976
797
|
expect(person.posts.size).to eq(1)
|
977
798
|
end
|
978
799
|
end
|
979
800
|
end
|
980
801
|
|
981
|
-
context
|
802
|
+
context 'when the association is polymorphic' do
|
803
|
+
context 'when the parent is a subclass' do
|
804
|
+
let(:video_game) { VideoGame.create! }
|
805
|
+
let(:rating) { video_game.ratings.build }
|
982
806
|
|
983
|
-
|
984
|
-
|
985
|
-
let(:video_game) do
|
986
|
-
VideoGame.create!
|
987
|
-
end
|
988
|
-
|
989
|
-
let(:rating) do
|
990
|
-
video_game.ratings.build
|
991
|
-
end
|
992
|
-
|
993
|
-
it "sets the parent on the child" do
|
807
|
+
it 'sets the parent on the child' do
|
994
808
|
expect(rating.ratable).to eq(video_game)
|
995
809
|
end
|
996
810
|
|
997
|
-
it
|
998
|
-
expect(rating.ratable_type).to eq(
|
811
|
+
it 'sets the correct polymorphic type' do
|
812
|
+
expect(rating.ratable_type).to eq('VideoGame')
|
999
813
|
end
|
1000
814
|
end
|
1001
815
|
|
1002
|
-
context
|
1003
|
-
|
1004
|
-
let(:movie)
|
1005
|
-
Movie.new
|
1006
|
-
end
|
1007
|
-
|
1008
|
-
let!(:rating) do
|
1009
|
-
movie.ratings.send(method, value: 3)
|
1010
|
-
end
|
816
|
+
context 'when the parent is a new record' do
|
817
|
+
let(:movie) { Movie.new }
|
818
|
+
let!(:rating) { movie.ratings.send(method, value: 3) }
|
1011
819
|
|
1012
|
-
it
|
820
|
+
it 'sets the foreign key on the association' do
|
1013
821
|
expect(rating.ratable_id).to eq(movie.id)
|
1014
822
|
end
|
1015
823
|
|
1016
|
-
it
|
824
|
+
it 'sets the base on the inverse association' do
|
1017
825
|
expect(rating.ratable).to eq(movie)
|
1018
826
|
end
|
1019
827
|
|
1020
|
-
it
|
828
|
+
it 'sets the attributes' do
|
1021
829
|
expect(rating.value).to eq(3)
|
1022
830
|
end
|
1023
831
|
|
1024
|
-
it
|
832
|
+
it 'does not save the target' do
|
1025
833
|
expect(rating).to be_new_record
|
1026
834
|
end
|
1027
835
|
|
1028
|
-
it
|
836
|
+
it 'adds the document to the target' do
|
1029
837
|
expect(movie.ratings.size).to eq(1)
|
1030
838
|
end
|
1031
839
|
|
1032
|
-
it
|
840
|
+
it 'does not perform validation' do
|
1033
841
|
expect(rating.errors).to be_empty
|
1034
842
|
end
|
1035
843
|
end
|
1036
844
|
|
1037
|
-
context
|
1038
|
-
|
1039
|
-
let(:movie)
|
1040
|
-
Movie.create!
|
1041
|
-
end
|
1042
|
-
|
1043
|
-
let!(:rating) do
|
1044
|
-
movie.ratings.send(method, value: 4)
|
1045
|
-
end
|
845
|
+
context 'when the parent is not a new record' do
|
846
|
+
let(:movie) { Movie.create! }
|
847
|
+
let!(:rating) { movie.ratings.send(method, value: 4) }
|
1046
848
|
|
1047
|
-
it
|
849
|
+
it 'sets the foreign key on the association' do
|
1048
850
|
expect(rating.ratable_id).to eq(movie.id)
|
1049
851
|
end
|
1050
852
|
|
1051
|
-
it
|
853
|
+
it 'sets the base on the inverse association' do
|
1052
854
|
expect(rating.ratable).to eq(movie)
|
1053
855
|
end
|
1054
856
|
|
1055
|
-
it
|
857
|
+
it 'sets the attributes' do
|
1056
858
|
expect(rating.value).to eq(4)
|
1057
859
|
end
|
1058
860
|
|
1059
|
-
it
|
861
|
+
it 'does not save the target' do
|
1060
862
|
expect(rating).to be_new_record
|
1061
863
|
end
|
1062
864
|
|
1063
|
-
it
|
865
|
+
it 'adds the document to the target' do
|
1064
866
|
expect(movie.ratings.size).to eq(1)
|
1065
867
|
end
|
1066
868
|
end
|
@@ -1068,296 +870,232 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
1068
870
|
end
|
1069
871
|
end
|
1070
872
|
|
1071
|
-
describe
|
1072
|
-
|
1073
|
-
|
1074
|
-
|
1075
|
-
context "when the parent has been persisted" do
|
1076
|
-
|
1077
|
-
let!(:person) do
|
1078
|
-
Person.create!
|
1079
|
-
end
|
1080
|
-
|
1081
|
-
context "when the children are persisted" do
|
1082
|
-
|
1083
|
-
let!(:post) do
|
1084
|
-
person.posts.create!(title: "Testing")
|
1085
|
-
end
|
873
|
+
describe '#clear' do
|
874
|
+
context 'when the association is not polymorphic' do
|
875
|
+
context 'when the parent has been persisted' do
|
876
|
+
let!(:person) { Person.create! }
|
1086
877
|
|
1087
|
-
|
1088
|
-
|
1089
|
-
|
878
|
+
context 'when the children are persisted' do
|
879
|
+
let!(:post) { person.posts.create!(title: 'Testing') }
|
880
|
+
let!(:association) { person.posts.clear }
|
1090
881
|
|
1091
|
-
it
|
882
|
+
it 'clears out the association' do
|
1092
883
|
expect(person.posts).to be_empty
|
1093
884
|
end
|
1094
885
|
|
1095
|
-
it
|
886
|
+
it 'marks the documents as deleted' do
|
1096
887
|
expect(post).to be_destroyed
|
1097
888
|
end
|
1098
889
|
|
1099
|
-
it
|
890
|
+
it 'deletes the documents from the db' do
|
1100
891
|
expect(person.reload.posts).to be_empty
|
1101
892
|
end
|
1102
893
|
|
1103
|
-
it
|
894
|
+
it 'returns the association' do
|
1104
895
|
expect(association).to be_empty
|
1105
896
|
end
|
1106
897
|
end
|
1107
898
|
|
1108
|
-
context
|
1109
|
-
|
1110
|
-
|
1111
|
-
person.posts.build(title: "Testing")
|
1112
|
-
end
|
1113
|
-
|
1114
|
-
let!(:association) do
|
899
|
+
context 'when the children are not persisted' do
|
900
|
+
before do
|
901
|
+
person.posts.build(title: 'Testing')
|
1115
902
|
person.posts.clear
|
1116
903
|
end
|
1117
904
|
|
1118
|
-
it
|
905
|
+
it 'clears out the association' do
|
1119
906
|
expect(person.posts).to be_empty
|
1120
907
|
end
|
1121
908
|
end
|
1122
909
|
end
|
1123
910
|
|
1124
|
-
context
|
1125
|
-
|
1126
|
-
let(:person) do
|
1127
|
-
Person.new
|
1128
|
-
end
|
1129
|
-
|
1130
|
-
let!(:post) do
|
1131
|
-
person.posts.build(title: "Testing")
|
1132
|
-
end
|
911
|
+
context 'when the parent is not persisted' do
|
912
|
+
let(:person) { Person.new }
|
1133
913
|
|
1134
|
-
|
914
|
+
before do
|
915
|
+
person.posts.build(title: 'Testing')
|
1135
916
|
person.posts.clear
|
1136
917
|
end
|
1137
918
|
|
1138
|
-
it
|
919
|
+
it 'clears out the association' do
|
1139
920
|
expect(person.posts).to be_empty
|
1140
921
|
end
|
1141
922
|
end
|
1142
923
|
end
|
1143
924
|
|
1144
|
-
context
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
let!(:movie) do
|
1149
|
-
Movie.create!
|
1150
|
-
end
|
1151
|
-
|
1152
|
-
context "when the children are persisted" do
|
1153
|
-
|
1154
|
-
let!(:rating) do
|
1155
|
-
movie.ratings.create!(value: 1)
|
1156
|
-
end
|
925
|
+
context 'when the association is polymorphic' do
|
926
|
+
context 'when the parent has been persisted' do
|
927
|
+
let!(:movie) { Movie.create! }
|
1157
928
|
|
1158
|
-
|
1159
|
-
|
1160
|
-
|
929
|
+
context 'when the children are persisted' do
|
930
|
+
let!(:rating) { movie.ratings.create!(value: 1) }
|
931
|
+
let!(:association) { movie.ratings.clear }
|
1161
932
|
|
1162
|
-
it
|
933
|
+
it 'clears out the association' do
|
1163
934
|
expect(movie.ratings).to be_empty
|
1164
935
|
end
|
1165
936
|
|
1166
|
-
it
|
1167
|
-
expect(rating).
|
937
|
+
it 'handles the proper dependent strategy' do
|
938
|
+
expect(rating).not_to be_destroyed
|
1168
939
|
end
|
1169
940
|
|
1170
|
-
it
|
941
|
+
it 'deletes the documents from the db' do
|
1171
942
|
expect(movie.reload.ratings).to be_empty
|
1172
943
|
end
|
1173
944
|
|
1174
|
-
it
|
945
|
+
it 'returns the association' do
|
1175
946
|
expect(association).to be_empty
|
1176
947
|
end
|
1177
948
|
end
|
1178
949
|
|
1179
|
-
context
|
1180
|
-
|
1181
|
-
let!(:rating) do
|
950
|
+
context 'when the children are not persisted' do
|
951
|
+
before do
|
1182
952
|
movie.ratings.build(value: 3)
|
1183
|
-
end
|
1184
|
-
|
1185
|
-
let!(:association) do
|
1186
953
|
movie.ratings.clear
|
1187
954
|
end
|
1188
955
|
|
1189
|
-
it
|
956
|
+
it 'clears out the association' do
|
1190
957
|
expect(movie.ratings).to be_empty
|
1191
958
|
end
|
1192
959
|
end
|
1193
960
|
end
|
1194
961
|
|
1195
|
-
context
|
1196
|
-
|
1197
|
-
let(:movie) do
|
1198
|
-
Movie.new
|
1199
|
-
end
|
962
|
+
context 'when the parent is not persisted' do
|
963
|
+
let(:movie) { Movie.new }
|
1200
964
|
|
1201
|
-
|
965
|
+
before do
|
1202
966
|
movie.ratings.build(value: 2)
|
1203
|
-
end
|
1204
|
-
|
1205
|
-
let!(:association) do
|
1206
967
|
movie.ratings.clear
|
1207
968
|
end
|
1208
969
|
|
1209
|
-
it
|
970
|
+
it 'clears out the association' do
|
1210
971
|
expect(movie.ratings).to be_empty
|
1211
972
|
end
|
1212
973
|
end
|
1213
974
|
end
|
1214
975
|
end
|
1215
976
|
|
1216
|
-
describe
|
1217
|
-
|
1218
|
-
|
1219
|
-
|
1220
|
-
|
1221
|
-
|
1222
|
-
let(:person) do
|
1223
|
-
Person.new
|
1224
|
-
end
|
1225
|
-
|
1226
|
-
let(:post) do
|
1227
|
-
Post.new
|
1228
|
-
end
|
977
|
+
describe '#concat' do
|
978
|
+
context 'when the associations are not polymorphic' do
|
979
|
+
context 'when the parent is a new record' do
|
980
|
+
let(:person) { Person.new }
|
981
|
+
let(:post) { Post.new }
|
1229
982
|
|
1230
983
|
before do
|
1231
|
-
person.posts.
|
984
|
+
person.posts.push post
|
1232
985
|
end
|
1233
986
|
|
1234
|
-
it
|
987
|
+
it 'sets the foreign key on the association' do
|
1235
988
|
expect(post.person_id).to eq(person.id)
|
1236
989
|
end
|
1237
990
|
|
1238
|
-
it
|
991
|
+
it 'sets the base on the inverse association' do
|
1239
992
|
expect(post.person).to eq(person)
|
1240
993
|
end
|
1241
994
|
|
1242
|
-
it
|
995
|
+
it 'sets the same instance on the inverse association' do
|
1243
996
|
expect(post.person).to eql(person)
|
1244
997
|
end
|
1245
998
|
|
1246
|
-
it
|
999
|
+
it 'does not save the target' do
|
1247
1000
|
expect(post).to be_new_record
|
1248
1001
|
end
|
1249
1002
|
|
1250
|
-
it
|
1003
|
+
it 'adds the document to the target' do
|
1251
1004
|
expect(person.posts.size).to eq(1)
|
1252
1005
|
end
|
1253
1006
|
end
|
1254
1007
|
|
1255
|
-
context
|
1256
|
-
|
1257
|
-
let!(:post) do
|
1258
|
-
Post.create!(title: "testing")
|
1259
|
-
end
|
1260
|
-
|
1008
|
+
context 'when appending in a parent create block' do
|
1009
|
+
let!(:post) { Post.create!(title: 'testing') }
|
1261
1010
|
let!(:person) do
|
1262
1011
|
Person.create! do |doc|
|
1263
|
-
doc.posts.
|
1012
|
+
doc.posts.push post
|
1264
1013
|
end
|
1265
1014
|
end
|
1266
1015
|
|
1267
|
-
it
|
1016
|
+
it 'adds the documents to the association' do
|
1268
1017
|
expect(person.posts).to eq([ post ])
|
1269
1018
|
end
|
1270
1019
|
|
1271
|
-
it
|
1020
|
+
it 'sets the foreign key on the inverse association' do
|
1272
1021
|
expect(post.person_id).to eq(person.id)
|
1273
1022
|
end
|
1274
1023
|
|
1275
|
-
it
|
1024
|
+
it 'saves the target' do
|
1276
1025
|
expect(post).to be_persisted
|
1277
1026
|
end
|
1278
1027
|
|
1279
|
-
it
|
1028
|
+
it 'adds the correct number of documents' do
|
1280
1029
|
expect(person.posts.size).to eq(1)
|
1281
1030
|
end
|
1282
1031
|
|
1283
|
-
it
|
1032
|
+
it 'persists the link' do
|
1284
1033
|
expect(person.reload.posts).to eq([ post ])
|
1285
1034
|
end
|
1286
1035
|
end
|
1287
1036
|
|
1288
|
-
context
|
1289
|
-
|
1290
|
-
let(:
|
1291
|
-
Person.create!
|
1292
|
-
end
|
1293
|
-
|
1294
|
-
let(:post) do
|
1295
|
-
Post.new
|
1296
|
-
end
|
1037
|
+
context 'when the parent is not a new record' do
|
1038
|
+
let(:person) { Person.create! }
|
1039
|
+
let(:post) { Post.new }
|
1297
1040
|
|
1298
|
-
let(:post_three)
|
1299
|
-
Post.new
|
1300
|
-
end
|
1041
|
+
let(:post_three) { Post.new }
|
1301
1042
|
|
1302
1043
|
before do
|
1303
|
-
person.posts.
|
1044
|
+
person.posts.push post, post_three
|
1304
1045
|
end
|
1305
1046
|
|
1306
|
-
it
|
1047
|
+
it 'sets the foreign key on the association' do
|
1307
1048
|
expect(post.person_id).to eq(person.id)
|
1308
1049
|
end
|
1309
1050
|
|
1310
|
-
it
|
1051
|
+
it 'sets the base on the inverse association' do
|
1311
1052
|
expect(post.person).to eq(person)
|
1312
1053
|
end
|
1313
1054
|
|
1314
|
-
it
|
1055
|
+
it 'sets the same instance on the inverse association' do
|
1315
1056
|
expect(post.person).to eql(person)
|
1316
1057
|
end
|
1317
1058
|
|
1318
|
-
it
|
1059
|
+
it 'saves the target' do
|
1319
1060
|
expect(post).to be_persisted
|
1320
1061
|
end
|
1321
1062
|
|
1322
|
-
it
|
1063
|
+
it 'adds the document to the target' do
|
1323
1064
|
expect(person.posts.count).to eq(2)
|
1324
1065
|
end
|
1325
1066
|
|
1326
|
-
context
|
1327
|
-
|
1328
|
-
let(:post_two) do
|
1329
|
-
Post.new(title: "Test")
|
1330
|
-
end
|
1067
|
+
context 'when documents already exist on the association' do
|
1068
|
+
let(:post_two) { Post.new(title: 'Test') }
|
1331
1069
|
|
1332
1070
|
before do
|
1333
|
-
person.posts.
|
1071
|
+
person.posts.push post_two
|
1334
1072
|
end
|
1335
1073
|
|
1336
|
-
it
|
1074
|
+
it 'sets the foreign key on the association' do
|
1337
1075
|
expect(post_two.person_id).to eq(person.id)
|
1338
1076
|
end
|
1339
1077
|
|
1340
|
-
it
|
1078
|
+
it 'sets the base on the inverse association' do
|
1341
1079
|
expect(post_two.person).to eq(person)
|
1342
1080
|
end
|
1343
1081
|
|
1344
|
-
it
|
1082
|
+
it 'sets the same instance on the inverse association' do
|
1345
1083
|
expect(post_two.person).to eql(person)
|
1346
1084
|
end
|
1347
1085
|
|
1348
|
-
it
|
1086
|
+
it 'saves the target' do
|
1349
1087
|
expect(post_two).to be_persisted
|
1350
1088
|
end
|
1351
1089
|
|
1352
|
-
it
|
1090
|
+
it 'adds the document to the target' do
|
1353
1091
|
expect(person.posts.count).to eq(3)
|
1354
1092
|
end
|
1355
1093
|
|
1356
|
-
it
|
1094
|
+
it 'contains the initial document in the target' do
|
1357
1095
|
expect(person.posts).to include(post)
|
1358
1096
|
end
|
1359
1097
|
|
1360
|
-
it
|
1098
|
+
it 'contains the added document in the target' do
|
1361
1099
|
expect(person.posts).to include(post_two)
|
1362
1100
|
end
|
1363
1101
|
end
|
@@ -1365,257 +1103,198 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
1365
1103
|
end
|
1366
1104
|
end
|
1367
1105
|
|
1368
|
-
context
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
let(:movie) do
|
1373
|
-
Movie.new
|
1374
|
-
end
|
1375
|
-
|
1376
|
-
let(:rating) do
|
1377
|
-
Rating.new
|
1378
|
-
end
|
1106
|
+
context 'when the associations are polymorphic' do
|
1107
|
+
context 'when the parent is a new record' do
|
1108
|
+
let(:movie) { Movie.new }
|
1109
|
+
let(:rating) { Rating.new }
|
1379
1110
|
|
1380
1111
|
before do
|
1381
|
-
movie.ratings.
|
1112
|
+
movie.ratings.push rating
|
1382
1113
|
end
|
1383
1114
|
|
1384
|
-
it
|
1115
|
+
it 'sets the foreign key on the association' do
|
1385
1116
|
expect(rating.ratable_id).to eq(movie.id)
|
1386
1117
|
end
|
1387
1118
|
|
1388
|
-
it
|
1119
|
+
it 'sets the base on the inverse association' do
|
1389
1120
|
expect(rating.ratable).to eq(movie)
|
1390
1121
|
end
|
1391
1122
|
|
1392
|
-
it
|
1123
|
+
it 'does not save the target' do
|
1393
1124
|
expect(rating).to be_new_record
|
1394
1125
|
end
|
1395
1126
|
|
1396
|
-
it
|
1127
|
+
it 'adds the document to the target' do
|
1397
1128
|
expect(movie.ratings.size).to eq(1)
|
1398
1129
|
end
|
1399
1130
|
end
|
1400
1131
|
|
1401
|
-
context
|
1402
|
-
|
1403
|
-
let(:
|
1404
|
-
Movie.create!
|
1405
|
-
end
|
1406
|
-
|
1407
|
-
let(:rating) do
|
1408
|
-
Rating.new
|
1409
|
-
end
|
1132
|
+
context 'when the parent is not a new record' do
|
1133
|
+
let(:movie) { Movie.create! }
|
1134
|
+
let(:rating) { Rating.new }
|
1410
1135
|
|
1411
1136
|
before do
|
1412
|
-
movie.ratings.
|
1137
|
+
movie.ratings.push rating
|
1413
1138
|
end
|
1414
1139
|
|
1415
|
-
it
|
1140
|
+
it 'sets the foreign key on the association' do
|
1416
1141
|
expect(rating.ratable_id).to eq(movie.id)
|
1417
1142
|
end
|
1418
1143
|
|
1419
|
-
it
|
1144
|
+
it 'sets the base on the inverse association' do
|
1420
1145
|
expect(rating.ratable).to eq(movie)
|
1421
1146
|
end
|
1422
1147
|
|
1423
|
-
it
|
1148
|
+
it 'saves the target' do
|
1424
1149
|
expect(rating).to be_persisted
|
1425
1150
|
end
|
1426
1151
|
|
1427
|
-
it
|
1152
|
+
it 'adds the document to the target' do
|
1428
1153
|
expect(movie.ratings.count).to eq(1)
|
1429
1154
|
end
|
1430
1155
|
end
|
1431
1156
|
end
|
1432
1157
|
|
1433
|
-
describe
|
1434
|
-
|
1435
|
-
let(:movie) do
|
1436
|
-
Movie.create!
|
1437
|
-
end
|
1438
|
-
|
1439
|
-
context "when documents have been persisted" do
|
1158
|
+
describe '#count' do
|
1159
|
+
let(:movie) { Movie.create! }
|
1440
1160
|
|
1441
|
-
|
1442
|
-
|
1443
|
-
end
|
1161
|
+
context 'when documents have been persisted' do
|
1162
|
+
before { movie.ratings.create!(value: 1) }
|
1444
1163
|
|
1445
|
-
it
|
1164
|
+
it 'returns the number of persisted documents' do
|
1446
1165
|
expect(movie.ratings.count).to eq(1)
|
1447
1166
|
end
|
1448
1167
|
|
1449
|
-
it
|
1450
|
-
expect(movie.ratings.count {|r| r.value >= 1 }).to eq(1)
|
1451
|
-
expect(movie.ratings.count {|r| r.value >= 2 }).to eq(0)
|
1168
|
+
it 'block form includes persisted results' do
|
1169
|
+
expect(movie.ratings.count { |r| r.value >= 1 }).to eq(1)
|
1170
|
+
expect(movie.ratings.count { |r| r.value >= 2 }).to eq(0)
|
1452
1171
|
end
|
1453
1172
|
end
|
1454
1173
|
|
1455
|
-
context
|
1456
|
-
|
1457
|
-
let!(:rating) do
|
1458
|
-
movie.ratings.build(value: 1)
|
1459
|
-
end
|
1174
|
+
context 'when documents have not been persisted' do
|
1175
|
+
before { movie.ratings.build(value: 1) }
|
1460
1176
|
|
1461
|
-
it
|
1177
|
+
it 'returns 0' do
|
1462
1178
|
expect(movie.ratings.count).to eq(0)
|
1463
1179
|
end
|
1464
1180
|
|
1465
|
-
it
|
1466
|
-
expect(movie.ratings.count {|r| r.value == 1 }).to eq(0)
|
1181
|
+
it 'block form does not include unpersisted results' do
|
1182
|
+
expect(movie.ratings.count { |r| r.value == 1 }).to eq(0)
|
1467
1183
|
end
|
1468
1184
|
end
|
1469
1185
|
|
1470
|
-
context
|
1471
|
-
|
1186
|
+
context 'when mixed persisted and unpersisted documents' do
|
1472
1187
|
before do
|
1473
1188
|
movie.ratings.create(value: 1)
|
1474
1189
|
movie.ratings.build(value: 2)
|
1475
1190
|
end
|
1476
1191
|
|
1477
|
-
it
|
1192
|
+
it 'returns 1' do
|
1478
1193
|
expect(movie.ratings.count).to eq(1)
|
1479
1194
|
end
|
1480
1195
|
|
1481
|
-
it
|
1482
|
-
expect(movie.ratings.count {|r| r.value >= 1 }).to eq(1)
|
1483
|
-
expect(movie.ratings.count {|r| r.value == 2 }).to eq(0)
|
1196
|
+
it 'block form includes only persisted results' do
|
1197
|
+
expect(movie.ratings.count { |r| r.value >= 1 }).to eq(1)
|
1198
|
+
expect(movie.ratings.count { |r| r.value == 2 }).to eq(0)
|
1484
1199
|
end
|
1485
1200
|
end
|
1486
1201
|
|
1487
|
-
context
|
1488
|
-
|
1489
|
-
it "returns false" do
|
1202
|
+
context 'when no document is added' do
|
1203
|
+
it 'returns false' do
|
1490
1204
|
expect(movie.ratings.any?).to be false
|
1491
1205
|
end
|
1492
1206
|
end
|
1493
1207
|
|
1494
|
-
context
|
1495
|
-
|
1496
|
-
context "when the documents are part of the association" do
|
1497
|
-
|
1208
|
+
context 'when new documents exist in the database' do
|
1209
|
+
context 'when the documents are part of the association' do
|
1498
1210
|
before do
|
1499
1211
|
Rating.create!(ratable: movie)
|
1500
1212
|
end
|
1501
1213
|
|
1502
|
-
it
|
1214
|
+
it 'returns the count from the db' do
|
1503
1215
|
expect(movie.ratings.count).to eq(1)
|
1504
1216
|
end
|
1505
1217
|
end
|
1506
1218
|
|
1507
|
-
context
|
1508
|
-
|
1219
|
+
context 'when the documents are not part of the association' do
|
1509
1220
|
before do
|
1510
1221
|
Rating.create!
|
1511
1222
|
end
|
1512
1223
|
|
1513
|
-
it
|
1224
|
+
it 'returns the count from the db' do
|
1514
1225
|
expect(movie.ratings.count).to eq(0)
|
1515
1226
|
end
|
1516
1227
|
end
|
1517
1228
|
end
|
1518
1229
|
end
|
1519
1230
|
|
1520
|
-
describe
|
1521
|
-
|
1231
|
+
describe '#any?' do
|
1522
1232
|
shared_examples 'does not query database when association is loaded' do
|
1523
|
-
|
1524
|
-
let(:fresh_movie) { Movie.find(movie.id) }
|
1233
|
+
let!(:fresh_movie) { Movie.find(movie.id) }
|
1525
1234
|
|
1526
1235
|
context 'when association is not loaded' do
|
1527
1236
|
it 'queries database on each call' do
|
1528
|
-
fresh_movie
|
1529
|
-
|
1530
|
-
expect_query(1) do
|
1531
|
-
fresh_movie.ratings.any?.should be expected_result
|
1532
|
-
end
|
1533
|
-
|
1534
|
-
expect_query(1) do
|
1535
|
-
fresh_movie.ratings.any?.should be expected_result
|
1536
|
-
end
|
1237
|
+
expect_query(1) { expect(fresh_movie.ratings.any?).to be expected_result }
|
1238
|
+
expect_query(1) { expect(fresh_movie.ratings.any?).to be expected_result }
|
1537
1239
|
end
|
1538
1240
|
|
1539
1241
|
context 'when using a block' do
|
1540
|
-
|
1541
|
-
fresh_movie
|
1542
|
-
|
1543
|
-
expect_query(1) do
|
1544
|
-
fresh_movie.ratings.any? { false }.should be false
|
1545
|
-
end
|
1242
|
+
def fresh_movie_ratings?
|
1243
|
+
fresh_movie.ratings.any? { false }
|
1244
|
+
end
|
1546
1245
|
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1246
|
+
it 'queries database on first call only' do
|
1247
|
+
expect_query(1) { expect(fresh_movie_ratings?).to be false }
|
1248
|
+
expect_no_queries { expect(fresh_movie_ratings?).to be false }
|
1550
1249
|
end
|
1551
1250
|
end
|
1552
1251
|
end
|
1553
1252
|
|
1554
1253
|
context 'when association is loaded' do
|
1555
1254
|
it 'does not query database' do
|
1556
|
-
fresh_movie
|
1557
|
-
|
1558
|
-
expect_query(1) do
|
1559
|
-
fresh_movie.ratings.any?.should be expected_result
|
1560
|
-
end
|
1561
|
-
|
1255
|
+
expect_query(1) { expect(fresh_movie.ratings.any?).to be expected_result }
|
1562
1256
|
fresh_movie.ratings.to_a
|
1563
|
-
|
1564
|
-
expect_no_queries do
|
1565
|
-
fresh_movie.ratings.any?.should be expected_result
|
1566
|
-
end
|
1257
|
+
expect_no_queries { expect(fresh_movie.ratings.any?).to be expected_result }
|
1567
1258
|
end
|
1568
1259
|
end
|
1569
1260
|
end
|
1570
1261
|
|
1571
|
-
let(:movie)
|
1572
|
-
Movie.create!
|
1573
|
-
end
|
1574
|
-
|
1575
|
-
context "when nothing exists on the association" do
|
1262
|
+
let(:movie) { Movie.create! }
|
1576
1263
|
|
1577
|
-
|
1578
|
-
|
1579
|
-
let!(:movie)
|
1580
|
-
|
1581
|
-
end
|
1264
|
+
context 'when nothing exists on the association' do
|
1265
|
+
context 'when no document is added' do
|
1266
|
+
let!(:movie) { Movie.create! }
|
1267
|
+
let(:expected_result) { false }
|
1582
1268
|
|
1583
|
-
it
|
1269
|
+
it 'returns false' do
|
1584
1270
|
expect(movie.ratings.any?).to be false
|
1585
1271
|
end
|
1586
1272
|
|
1587
|
-
let(:expected_result) { false }
|
1588
1273
|
include_examples 'does not query database when association is loaded'
|
1589
1274
|
end
|
1590
1275
|
|
1591
|
-
context
|
1592
|
-
|
1276
|
+
context 'when the document is destroyed' do
|
1593
1277
|
before do
|
1594
1278
|
Rating.create!
|
1595
1279
|
end
|
1596
1280
|
|
1597
|
-
let!(:movie)
|
1598
|
-
Movie.create!
|
1599
|
-
end
|
1281
|
+
let!(:movie) { Movie.create! }
|
1600
1282
|
|
1601
|
-
it
|
1283
|
+
it 'returns false' do
|
1602
1284
|
movie.destroy
|
1603
1285
|
expect(movie.ratings.any?).to be false
|
1604
1286
|
end
|
1605
1287
|
end
|
1606
1288
|
end
|
1607
1289
|
|
1608
|
-
context
|
1609
|
-
|
1610
|
-
let!(:movie) do
|
1611
|
-
Movie.create!
|
1612
|
-
end
|
1290
|
+
context 'when appending to a association and _loaded/_unloaded are empty' do
|
1291
|
+
let!(:movie) { Movie.create! }
|
1613
1292
|
|
1614
1293
|
before do
|
1615
1294
|
movie.ratings << Rating.new
|
1616
1295
|
end
|
1617
1296
|
|
1618
|
-
it
|
1297
|
+
it 'returns true' do
|
1619
1298
|
expect(movie.ratings.any?).to be true
|
1620
1299
|
end
|
1621
1300
|
|
@@ -1633,278 +1312,217 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
1633
1312
|
|
1634
1313
|
context 'when association is loaded' do
|
1635
1314
|
it 'does not query database' do
|
1636
|
-
expect_no_queries
|
1637
|
-
movie.ratings.any?.should be true
|
1638
|
-
end
|
1639
|
-
|
1315
|
+
expect_no_queries { expect(movie.ratings.any?).to be true }
|
1640
1316
|
movie.ratings.to_a
|
1641
|
-
|
1642
|
-
expect_no_queries do
|
1643
|
-
movie.ratings.any?.should be true
|
1644
|
-
end
|
1317
|
+
expect_no_queries { expect(movie.ratings.any?).to be true }
|
1645
1318
|
end
|
1646
1319
|
end
|
1647
1320
|
end
|
1648
1321
|
|
1649
|
-
context
|
1322
|
+
context 'when appending to an association in a transaction' do
|
1650
1323
|
require_transaction_support
|
1651
1324
|
|
1652
|
-
let!(:movie)
|
1653
|
-
|
1325
|
+
let!(:movie) { Movie.create! }
|
1326
|
+
|
1327
|
+
def with_transaction_via(model, &block)
|
1328
|
+
model.with_session do |session|
|
1329
|
+
session.with_transaction(&block)
|
1330
|
+
end
|
1654
1331
|
end
|
1655
1332
|
|
1656
|
-
it
|
1657
|
-
movie
|
1658
|
-
|
1659
|
-
|
1660
|
-
expect(movie.ratings.any?).to be true
|
1661
|
-
end
|
1333
|
+
it 'returns true' do
|
1334
|
+
with_transaction_via(movie) do
|
1335
|
+
expect { movie.ratings << Rating.new }.not_to raise_error
|
1336
|
+
expect(movie.ratings.any?).to be true
|
1662
1337
|
end
|
1663
1338
|
end
|
1664
1339
|
end
|
1665
1340
|
|
1666
|
-
context
|
1341
|
+
context 'when documents have been persisted' do
|
1342
|
+
let(:expected_result) { true }
|
1667
1343
|
|
1668
|
-
|
1344
|
+
before do
|
1669
1345
|
movie.ratings.create!(value: 1)
|
1670
1346
|
end
|
1671
1347
|
|
1672
|
-
it
|
1348
|
+
it 'returns true' do
|
1673
1349
|
expect(movie.ratings.any?).to be true
|
1674
1350
|
end
|
1675
1351
|
|
1676
|
-
let(:expected_result) { true }
|
1677
1352
|
include_examples 'does not query database when association is loaded'
|
1678
1353
|
end
|
1679
1354
|
|
1680
|
-
context
|
1681
|
-
|
1682
|
-
let!(:rating) do
|
1355
|
+
context 'when documents have not been persisted' do
|
1356
|
+
before do
|
1683
1357
|
movie.ratings.build(value: 1)
|
1684
1358
|
end
|
1685
1359
|
|
1686
|
-
it
|
1360
|
+
it 'returns false' do
|
1687
1361
|
expect(movie.ratings.any?).to be true
|
1688
1362
|
end
|
1689
1363
|
end
|
1690
1364
|
|
1691
|
-
context
|
1365
|
+
context 'when new documents exist in the database' do
|
1692
1366
|
before do
|
1693
1367
|
Rating.create!(ratable: movie)
|
1694
1368
|
end
|
1695
1369
|
|
1696
|
-
it
|
1370
|
+
it 'returns true' do
|
1697
1371
|
expect(movie.ratings.any?).to be true
|
1698
1372
|
end
|
1699
1373
|
end
|
1700
1374
|
end
|
1701
1375
|
|
1702
|
-
describe
|
1376
|
+
describe '#create' do
|
1377
|
+
context 'when providing multiple attributes' do
|
1378
|
+
let(:person) { Person.create! }
|
1379
|
+
let!(:posts) { person.posts.create!([ { text: 'Test1' }, { text: 'Test2' } ]) }
|
1703
1380
|
|
1704
|
-
|
1705
|
-
|
1706
|
-
let(:person) do
|
1707
|
-
Person.create!
|
1708
|
-
end
|
1709
|
-
|
1710
|
-
let!(:posts) do
|
1711
|
-
person.posts.create!([{ text: "Test1" }, { text: "Test2" }])
|
1712
|
-
end
|
1713
|
-
|
1714
|
-
it "creates multiple documents" do
|
1381
|
+
it 'creates multiple documents' do
|
1715
1382
|
expect(posts.size).to eq(2)
|
1716
1383
|
end
|
1717
1384
|
|
1718
|
-
it
|
1719
|
-
expect(posts.first.text).to eq(
|
1385
|
+
it 'sets the first attributes' do
|
1386
|
+
expect(posts.first.text).to eq('Test1')
|
1720
1387
|
end
|
1721
1388
|
|
1722
|
-
it
|
1723
|
-
expect(posts.last.text).to eq(
|
1389
|
+
it 'sets the second attributes' do
|
1390
|
+
expect(posts.last.text).to eq('Test2')
|
1724
1391
|
end
|
1725
1392
|
|
1726
|
-
it
|
1393
|
+
it 'persists the children' do
|
1727
1394
|
expect(person.posts.count).to eq(2)
|
1728
1395
|
end
|
1729
1396
|
end
|
1730
1397
|
|
1731
|
-
context
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
let(:person) do
|
1736
|
-
Person.new
|
1737
|
-
end
|
1398
|
+
context 'when the association is not polymorphic' do
|
1399
|
+
context 'when the parent is a new record' do
|
1400
|
+
let(:person) { Person.new }
|
1401
|
+
let(:post) { person.posts.create!(text: 'Testing') }
|
1738
1402
|
|
1739
|
-
|
1740
|
-
person.posts.create!(text: "Testing")
|
1741
|
-
end
|
1742
|
-
|
1743
|
-
it "raises an unsaved document error" do
|
1403
|
+
it 'raises an unsaved document error' do
|
1744
1404
|
expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
|
1745
1405
|
end
|
1746
1406
|
end
|
1747
1407
|
|
1748
|
-
context
|
1749
|
-
|
1750
|
-
|
1751
|
-
|
1752
|
-
let(:person) do
|
1753
|
-
Person.create!
|
1754
|
-
end
|
1755
|
-
|
1756
|
-
let!(:post) do
|
1757
|
-
person.posts.create!(text: "Testing")
|
1758
|
-
end
|
1408
|
+
context 'when.creating the document' do
|
1409
|
+
context 'when the operation is successful' do
|
1410
|
+
let(:person) { Person.create! }
|
1411
|
+
let!(:post) { person.posts.create!(text: 'Testing') }
|
1759
1412
|
|
1760
|
-
it
|
1413
|
+
it 'creates the document' do
|
1761
1414
|
expect(person.posts).to eq([ post ])
|
1762
1415
|
end
|
1763
1416
|
end
|
1764
1417
|
|
1765
|
-
context
|
1418
|
+
context 'when the operation fails' do
|
1419
|
+
let(:person) { Person.create! }
|
1420
|
+
let!(:existing) { Post.create! }
|
1766
1421
|
|
1767
|
-
|
1768
|
-
|
1769
|
-
|
1770
|
-
|
1771
|
-
let!(:existing) do
|
1772
|
-
Post.create!
|
1773
|
-
end
|
1774
|
-
|
1775
|
-
it "raises an error" do
|
1776
|
-
expect {
|
1777
|
-
person.posts.create! do |doc|
|
1778
|
-
doc._id = existing.id
|
1779
|
-
end
|
1780
|
-
}.to raise_error(Mongo::Error::OperationFailure)
|
1422
|
+
it 'raises an error' do
|
1423
|
+
expect { person.posts.create! { |doc| doc._id = existing.id } }
|
1424
|
+
.to raise_error(Mongo::Error::OperationFailure)
|
1781
1425
|
end
|
1782
1426
|
end
|
1783
1427
|
end
|
1784
1428
|
|
1785
|
-
context
|
1786
|
-
|
1787
|
-
let(:person) do
|
1788
|
-
Person.create!
|
1789
|
-
end
|
1790
|
-
|
1429
|
+
context 'when the parent is not a new record' do
|
1430
|
+
let(:person) { Person.create! }
|
1791
1431
|
let!(:post) do
|
1792
|
-
person.posts.create!(text:
|
1793
|
-
post.content =
|
1432
|
+
person.posts.create!(text: 'Testing') do |post|
|
1433
|
+
post.content = 'The Content'
|
1794
1434
|
end
|
1795
1435
|
end
|
1796
1436
|
|
1797
|
-
it
|
1437
|
+
it 'sets the foreign key on the association' do
|
1798
1438
|
expect(post.person_id).to eq(person.id)
|
1799
1439
|
end
|
1800
1440
|
|
1801
|
-
it
|
1441
|
+
it 'sets the base on the inverse association' do
|
1802
1442
|
expect(post.person).to eq(person)
|
1803
1443
|
end
|
1804
1444
|
|
1805
|
-
it
|
1806
|
-
expect(post.text).to eq(
|
1445
|
+
it 'sets the attributes' do
|
1446
|
+
expect(post.text).to eq('Testing')
|
1807
1447
|
end
|
1808
1448
|
|
1809
|
-
it
|
1810
|
-
expect(post).
|
1449
|
+
it 'saves the target' do
|
1450
|
+
expect(post).not_to be_a_new_record
|
1811
1451
|
end
|
1812
1452
|
|
1813
|
-
it
|
1814
|
-
expect(post.content).to eq(
|
1453
|
+
it 'calls the passed block' do
|
1454
|
+
expect(post.content).to eq('The Content')
|
1815
1455
|
end
|
1816
1456
|
|
1817
|
-
it
|
1457
|
+
it 'adds the document to the target' do
|
1818
1458
|
expect(person.posts.count).to eq(1)
|
1819
1459
|
end
|
1820
1460
|
end
|
1821
1461
|
|
1822
|
-
context
|
1462
|
+
context 'when passing a new object' do
|
1463
|
+
let!(:odd) { Odd.create!(name: 'one') }
|
1823
1464
|
|
1824
|
-
|
1825
|
-
|
1826
|
-
end
|
1827
|
-
|
1828
|
-
let!(:even) do
|
1829
|
-
odd.evens.create!(name: 'two', odds: [Odd.new(name: 'three')])
|
1465
|
+
before do
|
1466
|
+
odd.evens.create!(name: 'two', odds: [ Odd.new(name: 'three') ])
|
1830
1467
|
end
|
1831
1468
|
|
1832
|
-
it
|
1469
|
+
it 'only push one even to the list' do
|
1833
1470
|
expect(odd.evens.count).to eq(1)
|
1834
1471
|
end
|
1835
1472
|
|
1836
|
-
it
|
1473
|
+
it 'saves the reference back' do
|
1837
1474
|
expect(odd.evens.first.odds.count).to eq(1)
|
1838
1475
|
end
|
1839
1476
|
|
1840
|
-
it
|
1477
|
+
it 'only saves one even' do
|
1841
1478
|
expect(Even.count).to eq(1)
|
1842
1479
|
end
|
1843
1480
|
|
1844
|
-
it
|
1481
|
+
it 'saves the first odd and the second' do
|
1845
1482
|
expect(Odd.count).to eq(2)
|
1846
1483
|
end
|
1847
1484
|
end
|
1848
1485
|
end
|
1849
1486
|
|
1850
|
-
context
|
1851
|
-
|
1852
|
-
|
1487
|
+
context 'when the association is polymorphic' do
|
1488
|
+
context 'when the parent is a new record' do
|
1489
|
+
let(:movie) { Movie.new }
|
1490
|
+
let(:rating) { movie.ratings.create!(value: 1) }
|
1853
1491
|
|
1854
|
-
|
1855
|
-
Movie.new
|
1856
|
-
end
|
1857
|
-
|
1858
|
-
let(:rating) do
|
1859
|
-
movie.ratings.create!(value: 1)
|
1860
|
-
end
|
1861
|
-
|
1862
|
-
it "raises an unsaved document error" do
|
1492
|
+
it 'raises an unsaved document error' do
|
1863
1493
|
expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
|
1864
1494
|
end
|
1865
1495
|
end
|
1866
1496
|
|
1867
|
-
context
|
1868
|
-
|
1869
|
-
let(:movie)
|
1870
|
-
Movie.create!
|
1871
|
-
end
|
1497
|
+
context 'when the parent is not a new record' do
|
1498
|
+
let(:movie) { Movie.create! }
|
1499
|
+
let!(:rating) { movie.ratings.create!(value: 3) }
|
1872
1500
|
|
1873
|
-
|
1874
|
-
movie.ratings.create!(value: 3)
|
1875
|
-
end
|
1876
|
-
|
1877
|
-
it "sets the foreign key on the association" do
|
1501
|
+
it 'sets the foreign key on the association' do
|
1878
1502
|
expect(rating.ratable_id).to eq(movie.id)
|
1879
1503
|
end
|
1880
1504
|
|
1881
|
-
it
|
1505
|
+
it 'sets the base on the inverse association' do
|
1882
1506
|
expect(rating.ratable).to eq(movie)
|
1883
1507
|
end
|
1884
1508
|
|
1885
|
-
it
|
1509
|
+
it 'sets the attributes' do
|
1886
1510
|
expect(rating.value).to eq(3)
|
1887
1511
|
end
|
1888
1512
|
|
1889
|
-
it
|
1890
|
-
expect(rating).
|
1513
|
+
it 'saves the target' do
|
1514
|
+
expect(rating).not_to be_new_record
|
1891
1515
|
end
|
1892
1516
|
|
1893
|
-
it
|
1517
|
+
it 'adds the document to the target' do
|
1894
1518
|
expect(movie.ratings.count).to eq(1)
|
1895
1519
|
end
|
1896
1520
|
end
|
1897
1521
|
end
|
1898
1522
|
|
1899
|
-
context
|
1900
|
-
|
1901
|
-
let(:
|
1902
|
-
Person.create!(username: 'arthurnn')
|
1903
|
-
end
|
1904
|
-
|
1905
|
-
let(:drug) do
|
1906
|
-
person.drugs.create!
|
1907
|
-
end
|
1523
|
+
context 'when using a different primary_key' do
|
1524
|
+
let(:person) { Person.create!(username: 'arthurnn') }
|
1525
|
+
let(:drug) { person.drugs.create! }
|
1908
1526
|
|
1909
1527
|
it 'saves pk value on fk field' do
|
1910
1528
|
expect(drug.person_id).to eq('arthurnn')
|
@@ -1912,194 +1530,137 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
1912
1530
|
end
|
1913
1531
|
end
|
1914
1532
|
|
1915
|
-
describe
|
1916
|
-
|
1917
|
-
|
1918
|
-
|
1919
|
-
let(:person) do
|
1920
|
-
Person.create!
|
1921
|
-
end
|
1922
|
-
|
1923
|
-
let!(:posts) do
|
1924
|
-
person.posts.create!([{ text: "Test1" }, { text: "Test2" }])
|
1925
|
-
end
|
1533
|
+
describe '#create!' do
|
1534
|
+
context 'when providing multiple attributes' do
|
1535
|
+
let(:person) { Person.create! }
|
1536
|
+
let!(:posts) { person.posts.create!([ { text: 'Test1' }, { text: 'Test2' } ]) }
|
1926
1537
|
|
1927
|
-
it
|
1538
|
+
it 'creates multiple documents' do
|
1928
1539
|
expect(posts.size).to eq(2)
|
1929
1540
|
end
|
1930
1541
|
|
1931
|
-
it
|
1932
|
-
expect(posts.first.text).to eq(
|
1542
|
+
it 'sets the first attributes' do
|
1543
|
+
expect(posts.first.text).to eq('Test1')
|
1933
1544
|
end
|
1934
1545
|
|
1935
|
-
it
|
1936
|
-
expect(posts.last.text).to eq(
|
1546
|
+
it 'sets the second attributes' do
|
1547
|
+
expect(posts.last.text).to eq('Test2')
|
1937
1548
|
end
|
1938
1549
|
|
1939
|
-
it
|
1550
|
+
it 'persists the children' do
|
1940
1551
|
expect(person.posts.count).to eq(2)
|
1941
1552
|
end
|
1942
1553
|
end
|
1943
1554
|
|
1944
|
-
context
|
1945
|
-
|
1946
|
-
|
1555
|
+
context 'when the association is not polymorphic' do
|
1556
|
+
context 'when the parent is a new record' do
|
1557
|
+
let(:person) { Person.new }
|
1558
|
+
let(:post) { person.posts.create!(title: 'Testing') }
|
1947
1559
|
|
1948
|
-
|
1949
|
-
Person.new
|
1950
|
-
end
|
1951
|
-
|
1952
|
-
let(:post) do
|
1953
|
-
person.posts.create!(title: "Testing")
|
1954
|
-
end
|
1955
|
-
|
1956
|
-
it "raises an unsaved document error" do
|
1560
|
+
it 'raises an unsaved document error' do
|
1957
1561
|
expect { post }.to raise_error(Mongoid::Errors::UnsavedDocument)
|
1958
1562
|
end
|
1959
1563
|
end
|
1960
1564
|
|
1961
|
-
context
|
1962
|
-
|
1963
|
-
let(:person)
|
1964
|
-
Person.create!
|
1965
|
-
end
|
1966
|
-
|
1967
|
-
let!(:post) do
|
1968
|
-
person.posts.create!(title: "Testing")
|
1969
|
-
end
|
1565
|
+
context 'when the parent is not a new record' do
|
1566
|
+
let(:person) { Person.create! }
|
1567
|
+
let!(:post) { person.posts.create!(title: 'Testing') }
|
1970
1568
|
|
1971
|
-
it
|
1569
|
+
it 'sets the foreign key on the association' do
|
1972
1570
|
expect(post.person_id).to eq(person.id)
|
1973
1571
|
end
|
1974
1572
|
|
1975
|
-
it
|
1573
|
+
it 'sets the base on the inverse association' do
|
1976
1574
|
expect(post.person).to eq(person)
|
1977
1575
|
end
|
1978
1576
|
|
1979
|
-
it
|
1980
|
-
expect(post.title).to eq(
|
1577
|
+
it 'sets the attributes' do
|
1578
|
+
expect(post.title).to eq('Testing')
|
1981
1579
|
end
|
1982
1580
|
|
1983
|
-
it
|
1984
|
-
expect(post).
|
1581
|
+
it 'saves the target' do
|
1582
|
+
expect(post).not_to be_a_new_record
|
1985
1583
|
end
|
1986
1584
|
|
1987
|
-
it
|
1585
|
+
it 'adds the document to the target' do
|
1988
1586
|
expect(person.posts.count).to eq(1)
|
1989
1587
|
end
|
1990
1588
|
|
1991
|
-
context
|
1992
|
-
|
1993
|
-
|
1994
|
-
|
1995
|
-
person.posts.create!(title: "$$$")
|
1996
|
-
}.to raise_error(Mongoid::Errors::Validations)
|
1589
|
+
context 'when validation fails' do
|
1590
|
+
it 'raises an error' do
|
1591
|
+
expect { person.posts.create!(title: '$$$') }
|
1592
|
+
.to raise_error(Mongoid::Errors::Validations)
|
1997
1593
|
end
|
1998
1594
|
end
|
1999
1595
|
end
|
2000
1596
|
end
|
2001
1597
|
|
2002
|
-
context
|
2003
|
-
|
2004
|
-
|
2005
|
-
|
2006
|
-
let(:movie) do
|
2007
|
-
Movie.new
|
2008
|
-
end
|
2009
|
-
|
2010
|
-
let(:rating) do
|
2011
|
-
movie.ratings.create!(value: 1)
|
2012
|
-
end
|
1598
|
+
context 'when the association is polymorphic' do
|
1599
|
+
context 'when the parent is a new record' do
|
1600
|
+
let(:movie) { Movie.new }
|
1601
|
+
let(:rating) { movie.ratings.create!(value: 1) }
|
2013
1602
|
|
2014
|
-
it
|
1603
|
+
it 'raises an unsaved document error' do
|
2015
1604
|
expect { rating }.to raise_error(Mongoid::Errors::UnsavedDocument)
|
2016
1605
|
end
|
2017
1606
|
end
|
2018
1607
|
|
2019
|
-
context
|
2020
|
-
|
2021
|
-
let(:movie)
|
2022
|
-
Movie.create!
|
2023
|
-
end
|
2024
|
-
|
2025
|
-
let!(:rating) do
|
2026
|
-
movie.ratings.create!(value: 4)
|
2027
|
-
end
|
1608
|
+
context 'when the parent is not a new record' do
|
1609
|
+
let(:movie) { Movie.create! }
|
1610
|
+
let!(:rating) { movie.ratings.create!(value: 4) }
|
2028
1611
|
|
2029
|
-
it
|
1612
|
+
it 'sets the foreign key on the association' do
|
2030
1613
|
expect(rating.ratable_id).to eq(movie.id)
|
2031
1614
|
end
|
2032
1615
|
|
2033
|
-
it
|
1616
|
+
it 'sets the base on the inverse association' do
|
2034
1617
|
expect(rating.ratable).to eq(movie)
|
2035
1618
|
end
|
2036
1619
|
|
2037
|
-
it
|
1620
|
+
it 'sets the attributes' do
|
2038
1621
|
expect(rating.value).to eq(4)
|
2039
1622
|
end
|
2040
1623
|
|
2041
|
-
it
|
2042
|
-
expect(rating).
|
1624
|
+
it 'saves the target' do
|
1625
|
+
expect(rating).not_to be_new_record
|
2043
1626
|
end
|
2044
1627
|
|
2045
|
-
it
|
1628
|
+
it 'adds the document to the target' do
|
2046
1629
|
expect(movie.ratings.count).to eq(1)
|
2047
1630
|
end
|
2048
1631
|
|
2049
|
-
context
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
movie.ratings.create!(value: 1000)
|
2054
|
-
}.to raise_error(Mongoid::Errors::Validations)
|
1632
|
+
context 'when validation fails' do
|
1633
|
+
it 'raises an error' do
|
1634
|
+
expect { movie.ratings.create!(value: 1000) }
|
1635
|
+
.to raise_error(Mongoid::Errors::Validations)
|
2055
1636
|
end
|
2056
1637
|
end
|
2057
1638
|
end
|
2058
1639
|
end
|
2059
1640
|
end
|
2060
1641
|
|
2061
|
-
describe
|
2062
|
-
|
2063
|
-
let(:base) do
|
2064
|
-
Movie.new
|
2065
|
-
end
|
1642
|
+
describe '#criteria' do
|
1643
|
+
let(:base) { Movie.new }
|
2066
1644
|
|
2067
|
-
context
|
1645
|
+
context 'when the association is polymorphic' do
|
1646
|
+
let(:association) { Movie.relations['ratings'] }
|
1647
|
+
let(:criteria) { association.criteria(base) }
|
2068
1648
|
|
2069
|
-
|
2070
|
-
Movie.relations["ratings"]
|
2071
|
-
end
|
2072
|
-
|
2073
|
-
let(:criteria) do
|
2074
|
-
association.criteria(base)
|
2075
|
-
end
|
2076
|
-
|
2077
|
-
it "includes the type in the criteria" do
|
1649
|
+
it 'includes the type in the criteria' do
|
2078
1650
|
expect(criteria.selector).to eq(
|
2079
|
-
|
2080
|
-
|
2081
|
-
"ratable_type" => "Movie"
|
2082
|
-
}
|
2083
|
-
)
|
1651
|
+
{ 'ratable_id' => base.id, 'ratable_type' => 'Movie' }
|
1652
|
+
)
|
2084
1653
|
end
|
2085
1654
|
end
|
2086
1655
|
|
2087
|
-
context
|
1656
|
+
context 'when the association is not polymorphic' do
|
1657
|
+
let(:association) { Person.relations['posts'] }
|
1658
|
+
let(:base) { Person.new }
|
2088
1659
|
|
2089
|
-
let(:association)
|
2090
|
-
Person.relations["posts"]
|
2091
|
-
end
|
2092
|
-
|
2093
|
-
let(:base) do
|
2094
|
-
Person.new
|
2095
|
-
end
|
1660
|
+
let(:criteria) { association.criteria(base) }
|
2096
1661
|
|
2097
|
-
|
2098
|
-
|
2099
|
-
end
|
2100
|
-
|
2101
|
-
it "does not include the type in the criteria" do
|
2102
|
-
expect(criteria.selector).to eq({ "person_id" => base.id })
|
1662
|
+
it 'does not include the type in the criteria' do
|
1663
|
+
expect(criteria.selector).to eq({ 'person_id' => base.id })
|
2103
1664
|
end
|
2104
1665
|
end
|
2105
1666
|
end
|
@@ -2214,131 +1775,115 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2214
1775
|
end
|
2215
1776
|
end
|
2216
1777
|
|
2217
|
-
[
|
2218
|
-
|
1778
|
+
%i[ delete_all destroy_all ].each do |method|
|
2219
1779
|
describe "##{method}" do
|
1780
|
+
context 'when the association is not polymorphic' do
|
1781
|
+
context 'when conditions are provided' do
|
1782
|
+
let(:person) { Person.create!(username: 'durran') }
|
1783
|
+
let!(:post2) { person.posts.create!(title: 'Test') }
|
2220
1784
|
|
2221
|
-
|
1785
|
+
before { person.posts.create!(title: 'Testing') }
|
2222
1786
|
|
2223
|
-
|
2224
|
-
|
2225
|
-
let(:person) do
|
2226
|
-
Person.create!(username: 'durran')
|
2227
|
-
end
|
2228
|
-
|
2229
|
-
let!(:post1) { person.posts.create!(title: "Testing") }
|
2230
|
-
let!(:post2) { person.posts.create!(title: "Test") }
|
2231
|
-
|
2232
|
-
it "removes the correct posts" do
|
2233
|
-
person.posts.send(method, { title: "Testing" })
|
1787
|
+
it 'removes the correct posts' do
|
1788
|
+
person.posts.send(method, { title: 'Testing' })
|
2234
1789
|
expect(person.posts.count).to eq(1)
|
2235
1790
|
expect(person.reload.posts_count).to eq(1) if method == :destroy_all
|
2236
1791
|
end
|
2237
1792
|
|
2238
|
-
it
|
2239
|
-
person.posts.send(method, { title:
|
2240
|
-
expect(Post.where(title:
|
1793
|
+
it 'deletes the documents from the database' do
|
1794
|
+
person.posts.send(method, { title: 'Testing' })
|
1795
|
+
expect(Post.where(title: 'Testing').count).to eq(0)
|
2241
1796
|
end
|
2242
1797
|
|
2243
|
-
it
|
2244
|
-
expect(person.posts.send(method, { title:
|
1798
|
+
it 'returns the number of documents deleted' do
|
1799
|
+
expect(person.posts.send(method, { title: 'Testing' })).to eq(1)
|
2245
1800
|
end
|
2246
1801
|
|
2247
|
-
it
|
2248
|
-
person.posts.send(method, { title:
|
2249
|
-
expect(person.posts).to eq([post2])
|
1802
|
+
it 'sets the association locally' do
|
1803
|
+
person.posts.send(method, { title: 'Testing' })
|
1804
|
+
expect(person.posts).to eq([ post2 ])
|
2250
1805
|
end
|
2251
1806
|
end
|
2252
1807
|
|
2253
|
-
context
|
2254
|
-
|
2255
|
-
let(:person) do
|
2256
|
-
Person.create!
|
2257
|
-
end
|
1808
|
+
context 'when conditions are not provided' do
|
1809
|
+
let(:person) { Person.create! }
|
2258
1810
|
|
2259
1811
|
before do
|
2260
|
-
person.posts.create!(title:
|
2261
|
-
person.posts.create!(title:
|
1812
|
+
person.posts.create!(title: 'Testing')
|
1813
|
+
person.posts.create!(title: 'Test')
|
2262
1814
|
end
|
2263
1815
|
|
2264
|
-
it
|
1816
|
+
it 'removes the correct posts' do
|
2265
1817
|
person.posts.send(method)
|
2266
1818
|
expect(person.posts.count).to eq(0)
|
2267
1819
|
end
|
2268
1820
|
|
2269
|
-
it
|
1821
|
+
it 'deletes the documents from the database' do
|
2270
1822
|
person.posts.send(method)
|
2271
|
-
expect(Post.where(title:
|
1823
|
+
expect(Post.where(title: 'Testing').count).to eq(0)
|
2272
1824
|
end
|
2273
1825
|
|
2274
|
-
it
|
1826
|
+
it 'returns the number of documents deleted' do
|
2275
1827
|
expect(person.posts.send(method)).to eq(2)
|
2276
1828
|
end
|
2277
1829
|
|
2278
|
-
it
|
1830
|
+
it 'sets the association locally' do
|
2279
1831
|
person.posts.send(method)
|
2280
1832
|
expect(person.posts).to eq([])
|
2281
1833
|
end
|
2282
1834
|
end
|
2283
1835
|
end
|
2284
1836
|
|
2285
|
-
context
|
2286
|
-
|
2287
|
-
|
2288
|
-
|
2289
|
-
let(:movie) do
|
2290
|
-
Movie.create!(title: "Bladerunner")
|
2291
|
-
end
|
2292
|
-
|
2293
|
-
let!(:rating1) { movie.ratings.create!(value: 1) }
|
1837
|
+
context 'when the association is polymorphic' do
|
1838
|
+
context 'when conditions are provided' do
|
1839
|
+
let(:movie) { Movie.create!(title: 'Bladerunner') }
|
2294
1840
|
let!(:rating2) { movie.ratings.create!(value: 2) }
|
2295
1841
|
|
2296
|
-
|
1842
|
+
before { movie.ratings.create!(value: 1) }
|
1843
|
+
|
1844
|
+
it 'removes the correct ratings' do
|
2297
1845
|
movie.ratings.send(method, { value: 1 })
|
2298
1846
|
expect(movie.ratings.count).to eq(1)
|
2299
1847
|
end
|
2300
1848
|
|
2301
|
-
it
|
1849
|
+
it 'deletes the documents from the database' do
|
2302
1850
|
movie.ratings.send(method, { value: 1 })
|
2303
1851
|
expect(Rating.where(value: 1).count).to eq(0)
|
2304
1852
|
end
|
2305
1853
|
|
2306
|
-
it
|
1854
|
+
it 'returns the number of documents deleted' do
|
2307
1855
|
expect(movie.ratings.send(method, { value: 1 })).to eq(1)
|
2308
1856
|
end
|
2309
1857
|
|
2310
|
-
it
|
1858
|
+
it 'sets the association locally' do
|
2311
1859
|
movie.ratings.send(method, { value: 1 })
|
2312
|
-
expect(movie.ratings).to eq([rating2])
|
1860
|
+
expect(movie.ratings).to eq([ rating2 ])
|
2313
1861
|
end
|
2314
1862
|
end
|
2315
1863
|
|
2316
|
-
context
|
2317
|
-
|
2318
|
-
let(:movie) do
|
2319
|
-
Movie.create!(title: "Bladerunner")
|
2320
|
-
end
|
1864
|
+
context 'when conditions are not provided' do
|
1865
|
+
let(:movie) { Movie.create!(title: 'Bladerunner') }
|
2321
1866
|
|
2322
1867
|
before do
|
2323
1868
|
movie.ratings.create!(value: 1)
|
2324
1869
|
movie.ratings.create!(value: 2)
|
2325
1870
|
end
|
2326
1871
|
|
2327
|
-
it
|
1872
|
+
it 'removes the correct ratings' do
|
2328
1873
|
movie.ratings.send(method)
|
2329
1874
|
expect(movie.ratings.count).to eq(0)
|
2330
1875
|
end
|
2331
1876
|
|
2332
|
-
it
|
1877
|
+
it 'deletes the documents from the database' do
|
2333
1878
|
movie.ratings.send(method)
|
2334
1879
|
expect(Rating.where(value: 1).count).to eq(0)
|
2335
1880
|
end
|
2336
1881
|
|
2337
|
-
it
|
1882
|
+
it 'returns the number of documents deleted' do
|
2338
1883
|
expect(movie.ratings.send(method)).to eq(2)
|
2339
1884
|
end
|
2340
1885
|
|
2341
|
-
it
|
1886
|
+
it 'sets the association locally' do
|
2342
1887
|
movie.ratings.send(method)
|
2343
1888
|
expect(movie.ratings).to eq([])
|
2344
1889
|
end
|
@@ -2347,52 +1892,36 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2347
1892
|
end
|
2348
1893
|
end
|
2349
1894
|
|
2350
|
-
describe
|
2351
|
-
|
2352
|
-
|
2353
|
-
expect(described_class).to_not be_embedded
|
1895
|
+
describe '.embedded?' do
|
1896
|
+
it 'returns false' do
|
1897
|
+
expect(described_class).not_to be_embedded
|
2354
1898
|
end
|
2355
1899
|
end
|
2356
1900
|
|
2357
|
-
describe
|
2358
|
-
|
2359
|
-
let!(:person) do
|
2360
|
-
Person.create!
|
2361
|
-
end
|
2362
|
-
|
2363
|
-
context "when documents exist in the database" do
|
1901
|
+
describe '#exists?' do
|
1902
|
+
let!(:person) { Person.create! }
|
2364
1903
|
|
1904
|
+
context 'when documents exist in the database' do
|
2365
1905
|
before do
|
2366
1906
|
person.posts.create!
|
2367
1907
|
end
|
2368
1908
|
|
2369
|
-
it
|
1909
|
+
it 'returns true' do
|
2370
1910
|
expect(person.posts.exists?).to be true
|
2371
1911
|
end
|
2372
1912
|
|
2373
1913
|
context 'when association is not loaded' do
|
2374
1914
|
it 'queries database on each call' do
|
2375
|
-
expect_query(1)
|
2376
|
-
|
2377
|
-
end
|
2378
|
-
|
2379
|
-
expect_query(1) do
|
2380
|
-
person.posts.exists?.should be true
|
2381
|
-
end
|
1915
|
+
expect_query(1) { expect(person.posts.exists?).to be true }
|
1916
|
+
expect_query(1) { expect(person.posts.exists?).to be true }
|
2382
1917
|
end
|
2383
1918
|
end
|
2384
1919
|
|
2385
1920
|
context 'when association is loaded' do
|
2386
1921
|
it 'queries database on each call' do
|
2387
|
-
expect_query(1)
|
2388
|
-
person.posts.exists?.should be true
|
2389
|
-
end
|
2390
|
-
|
1922
|
+
expect_query(1) { expect(person.posts.exists?).to be true }
|
2391
1923
|
person.posts.to_a
|
2392
|
-
|
2393
|
-
expect_query(1) do
|
2394
|
-
person.posts.exists?.should be true
|
2395
|
-
end
|
1924
|
+
expect_query(1) { expect(person.posts.exists?).to be true }
|
2396
1925
|
end
|
2397
1926
|
end
|
2398
1927
|
|
@@ -2433,72 +1962,50 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2433
1962
|
end
|
2434
1963
|
end
|
2435
1964
|
|
2436
|
-
context
|
2437
|
-
|
1965
|
+
context 'when documents exist in application but not in database' do
|
2438
1966
|
before do
|
2439
1967
|
person.posts.build
|
2440
1968
|
end
|
2441
1969
|
|
2442
|
-
it
|
1970
|
+
it 'returns false' do
|
2443
1971
|
expect(person.posts.exists?).to be false
|
2444
1972
|
end
|
2445
1973
|
|
2446
1974
|
context 'when association is not loaded' do
|
2447
1975
|
it 'queries database on each call' do
|
2448
|
-
expect_query(1)
|
2449
|
-
|
2450
|
-
end
|
2451
|
-
|
2452
|
-
expect_query(1) do
|
2453
|
-
person.posts.exists?.should be false
|
2454
|
-
end
|
1976
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
1977
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2455
1978
|
end
|
2456
1979
|
end
|
2457
1980
|
|
2458
1981
|
context 'when association is loaded' do
|
2459
1982
|
it 'queries database on each call' do
|
2460
|
-
expect_query(1)
|
2461
|
-
person.posts.exists?.should be false
|
2462
|
-
end
|
2463
|
-
|
1983
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2464
1984
|
person.posts.to_a
|
2465
|
-
|
2466
|
-
expect_query(1) do
|
2467
|
-
person.posts.exists?.should be false
|
2468
|
-
end
|
1985
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2469
1986
|
end
|
2470
1987
|
end
|
2471
1988
|
end
|
2472
1989
|
|
2473
|
-
context
|
2474
|
-
|
2475
|
-
it "returns false" do
|
1990
|
+
context 'when no documents exist' do
|
1991
|
+
it 'returns false' do
|
2476
1992
|
expect(person.posts.exists?).to be false
|
2477
1993
|
end
|
2478
1994
|
|
2479
1995
|
context 'when association is not loaded' do
|
2480
1996
|
it 'queries database on each call' do
|
2481
|
-
expect_query(1)
|
2482
|
-
|
2483
|
-
end
|
2484
|
-
|
2485
|
-
expect_query(1) do
|
2486
|
-
person.posts.exists?.should be false
|
2487
|
-
end
|
1997
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
1998
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2488
1999
|
end
|
2489
2000
|
end
|
2490
2001
|
|
2491
2002
|
context 'when association is loaded' do
|
2492
2003
|
it 'queries database on each call' do
|
2493
|
-
expect_query(1)
|
2494
|
-
person.posts.exists?.should be false
|
2495
|
-
end
|
2004
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2496
2005
|
|
2497
2006
|
person.posts.to_a
|
2498
2007
|
|
2499
|
-
expect_query(1)
|
2500
|
-
person.posts.exists?.should be false
|
2501
|
-
end
|
2008
|
+
expect_query(1) { expect(person.posts.exists?).to be false }
|
2502
2009
|
end
|
2503
2010
|
end
|
2504
2011
|
|
@@ -2510,128 +2017,94 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2510
2017
|
end
|
2511
2018
|
end
|
2512
2019
|
|
2513
|
-
describe
|
2514
|
-
|
2515
|
-
|
2516
|
-
|
2517
|
-
let(:person) do
|
2518
|
-
Person.create!
|
2519
|
-
end
|
2520
|
-
|
2521
|
-
let(:post_id) do
|
2522
|
-
person.posts.first.id
|
2523
|
-
end
|
2020
|
+
describe '#find' do
|
2021
|
+
context 'when iterating after the find' do
|
2022
|
+
let(:person) { Person.create! }
|
2023
|
+
let(:post_id) { person.posts.first.id }
|
2524
2024
|
|
2525
2025
|
before do
|
2526
2026
|
5.times { person.posts.create! }
|
2527
2027
|
end
|
2528
2028
|
|
2529
|
-
it
|
2530
|
-
expect {
|
2531
|
-
person.posts.
|
2532
|
-
}.not_to change { person.posts.to_a.size }
|
2029
|
+
it 'does not change the in memory size' do
|
2030
|
+
expect { person.posts.find(post_id) }
|
2031
|
+
.not_to(change { person.posts.to_a.size })
|
2533
2032
|
end
|
2534
2033
|
end
|
2535
2034
|
|
2536
|
-
context
|
2035
|
+
context 'when the association is not polymorphic' do
|
2036
|
+
let(:person) { Person.create! }
|
2037
|
+
let!(:post_one) { person.posts.create!(title: 'Test') }
|
2038
|
+
let!(:post_two) { person.posts.create!(title: 'OMG I has associations') }
|
2537
2039
|
|
2538
|
-
|
2539
|
-
|
2540
|
-
|
2541
|
-
|
2542
|
-
let!(:post_one) do
|
2543
|
-
person.posts.create!(title: "Test")
|
2544
|
-
end
|
2545
|
-
|
2546
|
-
let!(:post_two) do
|
2547
|
-
person.posts.create!(title: "OMG I has associations")
|
2548
|
-
end
|
2549
|
-
|
2550
|
-
context "when providing an id" do
|
2040
|
+
context 'when providing an id' do
|
2041
|
+
context 'when the id matches' do
|
2042
|
+
let(:post) { person.posts.find(post_one.id) }
|
2551
2043
|
|
2552
|
-
|
2553
|
-
|
2554
|
-
let(:post) do
|
2555
|
-
person.posts.find(post_one.id)
|
2556
|
-
end
|
2557
|
-
|
2558
|
-
it "returns the matching document" do
|
2044
|
+
it 'returns the matching document' do
|
2559
2045
|
expect(post).to eq(post_one)
|
2560
2046
|
end
|
2561
2047
|
end
|
2562
2048
|
|
2563
|
-
context
|
2564
|
-
|
2565
|
-
let(:post) do
|
2566
|
-
Post.create!(title: "Unscoped")
|
2567
|
-
end
|
2049
|
+
context 'when the id matches but is not scoped to the association' do
|
2050
|
+
let(:post) { Post.create!(title: 'Unscoped') }
|
2568
2051
|
|
2569
|
-
it
|
2570
|
-
expect {
|
2571
|
-
|
2572
|
-
|
2052
|
+
it 'raises an error' do
|
2053
|
+
expect { person.posts.find(post.id) }
|
2054
|
+
.to raise_error(Mongoid::Errors::DocumentNotFound,
|
2055
|
+
/Document\(s\) not found for class Post with id\(s\)/)
|
2573
2056
|
end
|
2574
2057
|
end
|
2575
2058
|
|
2576
|
-
context
|
2577
|
-
|
2578
|
-
context "when config set to raise error" do
|
2059
|
+
context 'when the id does not match' do
|
2060
|
+
context 'when config set to raise error' do
|
2579
2061
|
config_override :raise_not_found_error, true
|
2580
2062
|
|
2581
|
-
it
|
2582
|
-
expect {
|
2583
|
-
|
2584
|
-
|
2063
|
+
it 'raises an error' do
|
2064
|
+
expect { person.posts.find(BSON::ObjectId.new) }
|
2065
|
+
.to raise_error(Mongoid::Errors::DocumentNotFound,
|
2066
|
+
/Document\(s\) not found for class Post with id\(s\)/)
|
2585
2067
|
end
|
2586
2068
|
end
|
2587
2069
|
|
2588
|
-
context
|
2070
|
+
context 'when config set not to raise error' do
|
2589
2071
|
config_override :raise_not_found_error, false
|
2590
2072
|
|
2591
|
-
let(:post)
|
2592
|
-
person.posts.find(BSON::ObjectId.new)
|
2593
|
-
end
|
2073
|
+
let(:post) { person.posts.find(BSON::ObjectId.new) }
|
2594
2074
|
|
2595
|
-
it
|
2075
|
+
it 'returns nil' do
|
2596
2076
|
expect(post).to be_nil
|
2597
2077
|
end
|
2598
2078
|
end
|
2599
2079
|
end
|
2600
2080
|
end
|
2601
2081
|
|
2602
|
-
context
|
2603
|
-
|
2604
|
-
|
2605
|
-
|
2606
|
-
let(:posts) do
|
2607
|
-
person.posts.find([ post_one.id, post_two.id ])
|
2608
|
-
end
|
2082
|
+
context 'when providing an array of ids' do
|
2083
|
+
context 'when the ids match' do
|
2084
|
+
let(:posts) { person.posts.find([ post_one.id, post_two.id ]) }
|
2609
2085
|
|
2610
|
-
it
|
2086
|
+
it 'returns the matching documents' do
|
2611
2087
|
expect(posts).to eq([ post_one, post_two ])
|
2612
2088
|
end
|
2613
2089
|
end
|
2614
2090
|
|
2615
|
-
context
|
2616
|
-
|
2617
|
-
context "when config set to raise error" do
|
2091
|
+
context 'when the ids do not match' do
|
2092
|
+
context 'when config set to raise error' do
|
2618
2093
|
config_override :raise_not_found_error, true
|
2619
2094
|
|
2620
|
-
it
|
2621
|
-
expect {
|
2622
|
-
|
2623
|
-
|
2095
|
+
it 'raises an error' do
|
2096
|
+
expect { person.posts.find([ BSON::ObjectId.new ]) }
|
2097
|
+
.to raise_error(Mongoid::Errors::DocumentNotFound,
|
2098
|
+
/Document\(s\) not found for class Post with id\(s\)/)
|
2624
2099
|
end
|
2625
2100
|
end
|
2626
2101
|
|
2627
|
-
context
|
2102
|
+
context 'when config set not to raise error' do
|
2628
2103
|
config_override :raise_not_found_error, false
|
2629
2104
|
|
2630
|
-
let(:posts)
|
2631
|
-
person.posts.find([ BSON::ObjectId.new ])
|
2632
|
-
end
|
2105
|
+
let(:posts) { person.posts.find([ BSON::ObjectId.new ]) }
|
2633
2106
|
|
2634
|
-
it
|
2107
|
+
it 'returns an empty array' do
|
2635
2108
|
expect(posts).to be_empty
|
2636
2109
|
end
|
2637
2110
|
end
|
@@ -2639,100 +2112,85 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2639
2112
|
end
|
2640
2113
|
end
|
2641
2114
|
|
2642
|
-
context
|
2115
|
+
context 'when the association is polymorphic' do
|
2116
|
+
let(:movie) { Movie.create! }
|
2117
|
+
let!(:rating_one) { movie.ratings.create!(value: 1) }
|
2118
|
+
let!(:rating_two) { movie.ratings.create!(value: 5) }
|
2643
2119
|
|
2644
|
-
|
2645
|
-
|
2646
|
-
|
2120
|
+
context 'when providing an id' do
|
2121
|
+
context 'when the id matches' do
|
2122
|
+
let(:rating) { movie.ratings.find(rating_one.id) }
|
2647
2123
|
|
2648
|
-
|
2649
|
-
movie.ratings.create!(value: 1)
|
2650
|
-
end
|
2651
|
-
|
2652
|
-
let!(:rating_two) do
|
2653
|
-
movie.ratings.create!(value: 5)
|
2654
|
-
end
|
2655
|
-
|
2656
|
-
context "when providing an id" do
|
2657
|
-
|
2658
|
-
context "when the id matches" do
|
2659
|
-
|
2660
|
-
let(:rating) do
|
2661
|
-
movie.ratings.find(rating_one.id)
|
2662
|
-
end
|
2663
|
-
|
2664
|
-
it "returns the matching document" do
|
2124
|
+
it 'returns the matching document' do
|
2665
2125
|
expect(rating).to eq(rating_one)
|
2666
2126
|
end
|
2667
2127
|
end
|
2668
2128
|
|
2669
|
-
context
|
2670
|
-
|
2671
|
-
context "when config set to raise error" do
|
2129
|
+
context 'when the id does not match' do
|
2130
|
+
context 'when config set to raise error' do
|
2672
2131
|
config_override :raise_not_found_error, true
|
2673
2132
|
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2133
|
+
let(:expected_error) { Mongoid::Errors::DocumentNotFound }
|
2134
|
+
let(:expected_message) do
|
2135
|
+
/Document\(s\) not found for class Rating with id\(s\)/
|
2136
|
+
end
|
2137
|
+
|
2138
|
+
it 'raises an error' do
|
2139
|
+
expect { movie.ratings.find(BSON::ObjectId.new) }
|
2140
|
+
.to raise_error(expected_error, expected_message)
|
2678
2141
|
end
|
2679
2142
|
end
|
2680
2143
|
|
2681
|
-
context
|
2144
|
+
context 'when config set not to raise error' do
|
2682
2145
|
config_override :raise_not_found_error, false
|
2683
2146
|
|
2684
|
-
let(:rating)
|
2685
|
-
movie.ratings.find(BSON::ObjectId.new)
|
2686
|
-
end
|
2147
|
+
let(:rating) { movie.ratings.find(BSON::ObjectId.new) }
|
2687
2148
|
|
2688
|
-
it
|
2149
|
+
it 'returns nil' do
|
2689
2150
|
expect(rating).to be_nil
|
2690
2151
|
end
|
2691
2152
|
end
|
2692
2153
|
end
|
2693
2154
|
end
|
2694
2155
|
|
2695
|
-
context
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
let(:ratings) do
|
2700
|
-
movie.ratings.find([ rating_one.id, rating_two.id ])
|
2701
|
-
end
|
2156
|
+
context 'when providing an array of ids' do
|
2157
|
+
context 'when the ids match' do
|
2158
|
+
let(:ratings) { movie.ratings.find([ rating_one.id, rating_two.id ]) }
|
2702
2159
|
|
2703
|
-
it
|
2160
|
+
it 'returns the first matching document' do
|
2704
2161
|
expect(ratings).to include(rating_one)
|
2705
2162
|
end
|
2706
2163
|
|
2707
|
-
it
|
2164
|
+
it 'returns the second matching document' do
|
2708
2165
|
expect(ratings).to include(rating_two)
|
2709
2166
|
end
|
2710
2167
|
|
2711
|
-
it
|
2168
|
+
it 'returns the correct number of documents' do
|
2712
2169
|
expect(ratings.size).to eq(2)
|
2713
2170
|
end
|
2714
2171
|
end
|
2715
2172
|
|
2716
|
-
context
|
2717
|
-
|
2718
|
-
context "when config set to raise error" do
|
2173
|
+
context 'when the ids do not match' do
|
2174
|
+
context 'when config set to raise error' do
|
2719
2175
|
config_override :raise_not_found_error, true
|
2720
2176
|
|
2721
|
-
|
2722
|
-
|
2723
|
-
|
2724
|
-
|
2177
|
+
let(:expected_error) { Mongoid::Errors::DocumentNotFound }
|
2178
|
+
let(:expected_message) do
|
2179
|
+
/Document\(s\) not found for class Rating with id\(s\)/
|
2180
|
+
end
|
2181
|
+
|
2182
|
+
it 'raises an error' do
|
2183
|
+
expect { movie.ratings.find([ BSON::ObjectId.new ]) }
|
2184
|
+
.to raise_error(expected_error, expected_message)
|
2725
2185
|
end
|
2726
2186
|
end
|
2727
2187
|
|
2728
|
-
context
|
2188
|
+
context 'when config set not to raise error' do
|
2729
2189
|
config_override :raise_not_found_error, false
|
2730
2190
|
|
2731
|
-
let(:ratings)
|
2732
|
-
movie.ratings.find([ BSON::ObjectId.new ])
|
2733
|
-
end
|
2191
|
+
let(:ratings) { movie.ratings.find([ BSON::ObjectId.new ]) }
|
2734
2192
|
|
2735
|
-
it
|
2193
|
+
it 'returns an empty array' do
|
2736
2194
|
expect(ratings).to be_empty
|
2737
2195
|
end
|
2738
2196
|
end
|
@@ -2740,732 +2198,538 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
2740
2198
|
end
|
2741
2199
|
end
|
2742
2200
|
|
2743
|
-
context
|
2744
|
-
let
|
2745
|
-
|
2746
|
-
|
2747
|
-
|
2748
|
-
let!(:post_one) do
|
2749
|
-
author.posts.create!(title: 'post one')
|
2750
|
-
end
|
2201
|
+
context 'with block' do
|
2202
|
+
let(:titles) { [ 'post one', 'post two' ] }
|
2203
|
+
let!(:author) { Person.create!(title: 'Person') }
|
2204
|
+
let!(:post_one) { author.posts.create!(title: titles[0]) }
|
2751
2205
|
|
2752
|
-
|
2753
|
-
author.posts.create!(title: 'post two')
|
2754
|
-
end
|
2206
|
+
before { author.posts.create!(title: titles[1]) }
|
2755
2207
|
|
2756
|
-
it
|
2208
|
+
it 'finds one' do
|
2757
2209
|
expect(
|
2758
2210
|
author.posts.find do |post|
|
2759
|
-
post.title ==
|
2211
|
+
post.title == titles[0]
|
2760
2212
|
end
|
2761
2213
|
).to be_a(Post)
|
2762
2214
|
end
|
2763
2215
|
|
2764
|
-
it
|
2216
|
+
it 'returns first match of multiple' do
|
2765
2217
|
expect(
|
2766
2218
|
author.posts.find do |post|
|
2767
|
-
|
2219
|
+
titles.include?(post.title)
|
2768
2220
|
end
|
2769
2221
|
).to eq(post_one)
|
2770
2222
|
end
|
2771
2223
|
|
2772
|
-
it
|
2224
|
+
it 'returns nil when not found' do
|
2773
2225
|
expect(
|
2774
2226
|
author.posts.find do |post|
|
2775
|
-
post.title == 'non
|
2227
|
+
post.title == 'non existing one'
|
2776
2228
|
end
|
2777
2229
|
).to be_nil
|
2778
2230
|
end
|
2779
2231
|
end
|
2780
2232
|
end
|
2781
2233
|
|
2782
|
-
describe
|
2783
|
-
|
2784
|
-
|
2234
|
+
describe '#find_or_create_by' do
|
2235
|
+
context 'when the association is not polymorphic' do
|
2236
|
+
let(:person) { Person.create! }
|
2237
|
+
let!(:post) { person.posts.create!(title: 'Testing') }
|
2785
2238
|
|
2786
|
-
|
2787
|
-
|
2788
|
-
end
|
2239
|
+
context 'when the document exists' do
|
2240
|
+
let(:found) { person.posts.find_or_create_by(title: 'Testing') }
|
2789
2241
|
|
2790
|
-
|
2791
|
-
person.posts.create!(title: "Testing")
|
2792
|
-
end
|
2793
|
-
|
2794
|
-
context "when the document exists" do
|
2795
|
-
|
2796
|
-
let(:found) do
|
2797
|
-
person.posts.find_or_create_by(title: "Testing")
|
2798
|
-
end
|
2799
|
-
|
2800
|
-
it "returns the document" do
|
2242
|
+
it 'returns the document' do
|
2801
2243
|
expect(found).to eq(post)
|
2802
2244
|
end
|
2803
2245
|
|
2804
|
-
it
|
2246
|
+
it 'keeps the document in the association' do
|
2805
2247
|
expect(found.person).to eq(person)
|
2806
2248
|
end
|
2807
2249
|
end
|
2808
2250
|
|
2809
|
-
context
|
2810
|
-
|
2811
|
-
context "when there is no criteria attached" do
|
2812
|
-
|
2251
|
+
context 'when the document does not exist' do
|
2252
|
+
context 'when there is no criteria attached' do
|
2813
2253
|
let(:found) do
|
2814
|
-
person.posts.find_or_create_by(title:
|
2815
|
-
post.content =
|
2254
|
+
person.posts.find_or_create_by(title: 'Test') do |post|
|
2255
|
+
post.content = 'The Content'
|
2816
2256
|
end
|
2817
2257
|
end
|
2818
2258
|
|
2819
|
-
it
|
2820
|
-
expect(found.title).to eq(
|
2259
|
+
it 'sets the new document attributes' do
|
2260
|
+
expect(found.title).to eq('Test')
|
2821
2261
|
end
|
2822
2262
|
|
2823
|
-
it
|
2263
|
+
it 'returns a newly persisted document' do
|
2824
2264
|
expect(found).to be_persisted
|
2825
2265
|
end
|
2826
2266
|
|
2827
|
-
it
|
2828
|
-
expect(found.content).to eq(
|
2267
|
+
it 'calls the passed block' do
|
2268
|
+
expect(found.content).to eq('The Content')
|
2829
2269
|
end
|
2830
2270
|
|
2831
|
-
it
|
2271
|
+
it 'keeps the document in the association' do
|
2832
2272
|
expect(found.person).to eq(person)
|
2833
2273
|
end
|
2834
2274
|
end
|
2835
2275
|
|
2836
|
-
context
|
2276
|
+
context 'when a criteria is attached' do
|
2277
|
+
let(:found) { person.posts.recent.find_or_create_by(title: 'Test') }
|
2837
2278
|
|
2838
|
-
|
2839
|
-
|
2840
|
-
end
|
2841
|
-
|
2842
|
-
it "sets the new document attributes" do
|
2843
|
-
expect(found.title).to eq("Test")
|
2279
|
+
it 'sets the new document attributes' do
|
2280
|
+
expect(found.title).to eq('Test')
|
2844
2281
|
end
|
2845
2282
|
|
2846
|
-
it
|
2283
|
+
it 'returns a newly persisted document' do
|
2847
2284
|
expect(found).to be_persisted
|
2848
2285
|
end
|
2849
2286
|
|
2850
|
-
it
|
2287
|
+
it 'keeps the document in the association' do
|
2851
2288
|
expect(found.person).to eq(person)
|
2852
2289
|
end
|
2853
2290
|
end
|
2854
2291
|
end
|
2855
2292
|
end
|
2856
2293
|
|
2857
|
-
context
|
2858
|
-
|
2859
|
-
let(:movie)
|
2860
|
-
Movie.create!
|
2861
|
-
end
|
2862
|
-
|
2863
|
-
let!(:rating) do
|
2864
|
-
movie.ratings.create!(value: 1)
|
2865
|
-
end
|
2294
|
+
context 'when the association is polymorphic' do
|
2295
|
+
let(:movie) { Movie.create! }
|
2296
|
+
let!(:rating) { movie.ratings.create!(value: 1) }
|
2866
2297
|
|
2867
|
-
context
|
2298
|
+
context 'when the document exists' do
|
2299
|
+
let(:found) { movie.ratings.find_or_create_by(value: 1) }
|
2868
2300
|
|
2869
|
-
|
2870
|
-
movie.ratings.find_or_create_by(value: 1)
|
2871
|
-
end
|
2872
|
-
|
2873
|
-
it "returns the document" do
|
2301
|
+
it 'returns the document' do
|
2874
2302
|
expect(found).to eq(rating)
|
2875
2303
|
end
|
2876
2304
|
|
2877
|
-
it
|
2305
|
+
it 'keeps the document in the association' do
|
2878
2306
|
expect(found.ratable).to eq(movie)
|
2879
2307
|
end
|
2880
2308
|
end
|
2881
2309
|
|
2882
|
-
context
|
2310
|
+
context 'when the document does not exist' do
|
2311
|
+
let(:found) { movie.ratings.find_or_create_by(value: 3) }
|
2883
2312
|
|
2884
|
-
|
2885
|
-
movie.ratings.find_or_create_by(value: 3)
|
2886
|
-
end
|
2887
|
-
|
2888
|
-
it "sets the new document attributes" do
|
2313
|
+
it 'sets the new document attributes' do
|
2889
2314
|
expect(found.value).to eq(3)
|
2890
2315
|
end
|
2891
2316
|
|
2892
|
-
it
|
2317
|
+
it 'returns a newly persisted document' do
|
2893
2318
|
expect(found).to be_persisted
|
2894
2319
|
end
|
2895
2320
|
|
2896
|
-
it
|
2321
|
+
it 'keeps the document in the association' do
|
2897
2322
|
expect(found.ratable).to eq(movie)
|
2898
2323
|
end
|
2899
2324
|
end
|
2900
2325
|
end
|
2901
2326
|
end
|
2902
2327
|
|
2903
|
-
describe
|
2904
|
-
|
2905
|
-
|
2328
|
+
describe '#find_or_create_by!' do
|
2329
|
+
context 'when the association is not polymorphic' do
|
2330
|
+
let(:person) { Person.create! }
|
2331
|
+
let!(:post) { person.posts.create!(title: 'Testing') }
|
2906
2332
|
|
2907
|
-
|
2908
|
-
|
2909
|
-
end
|
2910
|
-
|
2911
|
-
let!(:post) do
|
2912
|
-
person.posts.create!(title: "Testing")
|
2913
|
-
end
|
2914
|
-
|
2915
|
-
context "when the document exists" do
|
2333
|
+
context 'when the document exists' do
|
2334
|
+
let(:found) { person.posts.find_or_create_by!(title: 'Testing') }
|
2916
2335
|
|
2917
|
-
|
2918
|
-
person.posts.find_or_create_by!(title: "Testing")
|
2919
|
-
end
|
2920
|
-
|
2921
|
-
it "returns the document" do
|
2336
|
+
it 'returns the document' do
|
2922
2337
|
expect(found).to eq(post)
|
2923
2338
|
end
|
2924
2339
|
|
2925
|
-
it
|
2340
|
+
it 'keeps the document in the association' do
|
2926
2341
|
expect(found.person).to eq(person)
|
2927
2342
|
end
|
2928
2343
|
end
|
2929
2344
|
|
2930
|
-
context
|
2931
|
-
|
2932
|
-
context "when there is no criteria attached" do
|
2933
|
-
|
2345
|
+
context 'when the document does not exist' do
|
2346
|
+
context 'when there is no criteria attached' do
|
2934
2347
|
let(:found) do
|
2935
|
-
person.posts.find_or_create_by!(title:
|
2936
|
-
post.content =
|
2348
|
+
person.posts.find_or_create_by!(title: 'Test') do |post|
|
2349
|
+
post.content = 'The Content'
|
2937
2350
|
end
|
2938
2351
|
end
|
2939
2352
|
|
2940
|
-
it
|
2941
|
-
expect(found.title).to eq(
|
2353
|
+
it 'sets the new document attributes' do
|
2354
|
+
expect(found.title).to eq('Test')
|
2942
2355
|
end
|
2943
2356
|
|
2944
|
-
it
|
2357
|
+
it 'returns a newly persisted document' do
|
2945
2358
|
expect(found).to be_persisted
|
2946
2359
|
end
|
2947
2360
|
|
2948
|
-
it
|
2949
|
-
expect(found.content).to eq(
|
2361
|
+
it 'calls the passed block' do
|
2362
|
+
expect(found.content).to eq('The Content')
|
2950
2363
|
end
|
2951
2364
|
|
2952
|
-
it
|
2365
|
+
it 'keeps the document in the association' do
|
2953
2366
|
expect(found.person).to eq(person)
|
2954
2367
|
end
|
2955
2368
|
end
|
2956
2369
|
|
2957
|
-
context
|
2958
|
-
|
2959
|
-
let(:found) do
|
2960
|
-
person.posts.recent.find_or_create_by!(title: "Test")
|
2961
|
-
end
|
2370
|
+
context 'when a criteria is attached' do
|
2371
|
+
let(:found) { person.posts.recent.find_or_create_by!(title: 'Test') }
|
2962
2372
|
|
2963
|
-
it
|
2964
|
-
expect(found.title).to eq(
|
2373
|
+
it 'sets the new document attributes' do
|
2374
|
+
expect(found.title).to eq('Test')
|
2965
2375
|
end
|
2966
2376
|
|
2967
|
-
it
|
2377
|
+
it 'returns a newly persisted document' do
|
2968
2378
|
expect(found).to be_persisted
|
2969
2379
|
end
|
2970
2380
|
|
2971
|
-
it
|
2381
|
+
it 'keeps the document in the association' do
|
2972
2382
|
expect(found.person).to eq(person)
|
2973
2383
|
end
|
2974
2384
|
end
|
2975
2385
|
end
|
2976
2386
|
end
|
2977
2387
|
|
2978
|
-
context
|
2979
|
-
|
2980
|
-
let(:movie)
|
2981
|
-
Movie.create!
|
2982
|
-
end
|
2983
|
-
|
2984
|
-
let!(:rating) do
|
2985
|
-
movie.ratings.create!(value: 1)
|
2986
|
-
end
|
2388
|
+
context 'when the association is polymorphic' do
|
2389
|
+
let(:movie) { Movie.create! }
|
2390
|
+
let!(:rating) { movie.ratings.create!(value: 1) }
|
2987
2391
|
|
2988
|
-
context
|
2989
|
-
|
2990
|
-
let(:found) do
|
2991
|
-
movie.ratings.find_or_create_by!(value: 1)
|
2992
|
-
end
|
2392
|
+
context 'when the document exists' do
|
2393
|
+
let(:found) { movie.ratings.find_or_create_by!(value: 1) }
|
2993
2394
|
|
2994
|
-
it
|
2395
|
+
it 'returns the document' do
|
2995
2396
|
expect(found).to eq(rating)
|
2996
2397
|
end
|
2997
2398
|
|
2998
|
-
it
|
2399
|
+
it 'keeps the document in the association' do
|
2999
2400
|
expect(found.ratable).to eq(movie)
|
3000
2401
|
end
|
3001
2402
|
end
|
3002
2403
|
|
3003
|
-
context
|
3004
|
-
|
3005
|
-
let(:found) do
|
3006
|
-
movie.ratings.find_or_create_by!(value: 3)
|
3007
|
-
end
|
2404
|
+
context 'when the document does not exist' do
|
2405
|
+
let(:found) { movie.ratings.find_or_create_by!(value: 3) }
|
3008
2406
|
|
3009
|
-
it
|
2407
|
+
it 'sets the new document attributes' do
|
3010
2408
|
expect(found.value).to eq(3)
|
3011
2409
|
end
|
3012
2410
|
|
3013
|
-
it
|
2411
|
+
it 'returns a newly persisted document' do
|
3014
2412
|
expect(found).to be_persisted
|
3015
2413
|
end
|
3016
2414
|
|
3017
|
-
it
|
2415
|
+
it 'keeps the document in the association' do
|
3018
2416
|
expect(found.ratable).to eq(movie)
|
3019
2417
|
end
|
3020
2418
|
|
3021
|
-
context
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
movie.comments.find_or_create_by!(title: "")
|
3026
|
-
}.to raise_error(Mongoid::Errors::Validations)
|
2419
|
+
context 'when validation fails' do
|
2420
|
+
it 'raises an error' do
|
2421
|
+
expect { movie.comments.find_or_create_by!(title: '') }
|
2422
|
+
.to raise_error(Mongoid::Errors::Validations)
|
3027
2423
|
end
|
3028
2424
|
end
|
3029
2425
|
end
|
3030
2426
|
end
|
3031
2427
|
end
|
3032
2428
|
|
3033
|
-
describe
|
3034
|
-
|
3035
|
-
|
3036
|
-
|
3037
|
-
let(:person) do
|
3038
|
-
Person.create!
|
3039
|
-
end
|
3040
|
-
|
3041
|
-
let!(:post) do
|
3042
|
-
person.posts.create!(title: "Testing")
|
3043
|
-
end
|
3044
|
-
|
3045
|
-
context "when the document exists" do
|
2429
|
+
describe '#find_or_initialize_by' do
|
2430
|
+
context 'when the association is not polymorphic' do
|
2431
|
+
let(:person) { Person.create! }
|
2432
|
+
let!(:post) { person.posts.create!(title: 'Testing') }
|
3046
2433
|
|
3047
|
-
|
3048
|
-
|
3049
|
-
end
|
2434
|
+
context 'when the document exists' do
|
2435
|
+
let(:found) { person.posts.find_or_initialize_by(title: 'Testing') }
|
3050
2436
|
|
3051
|
-
it
|
2437
|
+
it 'returns the document' do
|
3052
2438
|
expect(found).to eq(post)
|
3053
2439
|
end
|
3054
2440
|
end
|
3055
2441
|
|
3056
|
-
context
|
3057
|
-
|
2442
|
+
context 'when the document does not exist' do
|
3058
2443
|
let(:found) do
|
3059
|
-
person.posts.find_or_initialize_by(title:
|
3060
|
-
post.content =
|
2444
|
+
person.posts.find_or_initialize_by(title: 'Test') do |post|
|
2445
|
+
post.content = 'The Content'
|
3061
2446
|
end
|
3062
2447
|
end
|
3063
2448
|
|
3064
|
-
it
|
3065
|
-
expect(found.title).to eq(
|
2449
|
+
it 'sets the new document attributes' do
|
2450
|
+
expect(found.title).to eq('Test')
|
3066
2451
|
end
|
3067
2452
|
|
3068
|
-
it
|
3069
|
-
expect(found).
|
2453
|
+
it 'returns a non persisted document' do
|
2454
|
+
expect(found).not_to be_persisted
|
3070
2455
|
end
|
3071
2456
|
|
3072
|
-
it
|
3073
|
-
expect(found.content).to eq(
|
2457
|
+
it 'calls the passed block' do
|
2458
|
+
expect(found.content).to eq('The Content')
|
3074
2459
|
end
|
3075
2460
|
end
|
3076
2461
|
end
|
3077
2462
|
|
3078
|
-
context
|
3079
|
-
|
3080
|
-
let(:movie)
|
3081
|
-
Movie.create!
|
3082
|
-
end
|
3083
|
-
|
3084
|
-
let!(:rating) do
|
3085
|
-
movie.ratings.create!(value: 1)
|
3086
|
-
end
|
2463
|
+
context 'when the association is polymorphic' do
|
2464
|
+
let(:movie) { Movie.create! }
|
2465
|
+
let!(:rating) { movie.ratings.create!(value: 1) }
|
3087
2466
|
|
3088
|
-
context
|
2467
|
+
context 'when the document exists' do
|
2468
|
+
let(:found) { movie.ratings.find_or_initialize_by(value: 1) }
|
3089
2469
|
|
3090
|
-
|
3091
|
-
movie.ratings.find_or_initialize_by(value: 1)
|
3092
|
-
end
|
3093
|
-
|
3094
|
-
it "returns the document" do
|
2470
|
+
it 'returns the document' do
|
3095
2471
|
expect(found).to eq(rating)
|
3096
2472
|
end
|
3097
2473
|
end
|
3098
2474
|
|
3099
|
-
context
|
2475
|
+
context 'when the document does not exist' do
|
2476
|
+
let(:found) { movie.ratings.find_or_initialize_by(value: 3) }
|
3100
2477
|
|
3101
|
-
|
3102
|
-
movie.ratings.find_or_initialize_by(value: 3)
|
3103
|
-
end
|
3104
|
-
|
3105
|
-
it "sets the new document attributes" do
|
2478
|
+
it 'sets the new document attributes' do
|
3106
2479
|
expect(found.value).to eq(3)
|
3107
2480
|
end
|
3108
2481
|
|
3109
|
-
it
|
3110
|
-
expect(found).
|
2482
|
+
it 'returns a non persisted document' do
|
2483
|
+
expect(found).not_to be_persisted
|
3111
2484
|
end
|
3112
2485
|
end
|
3113
2486
|
end
|
3114
2487
|
end
|
3115
2488
|
|
3116
|
-
describe
|
3117
|
-
|
3118
|
-
|
2489
|
+
describe '#initialize' do
|
2490
|
+
context 'when an illegal mixed association exists' do
|
2491
|
+
let(:post) { Post.new }
|
3119
2492
|
|
3120
|
-
|
3121
|
-
|
3122
|
-
|
3123
|
-
|
3124
|
-
it "raises an error" do
|
3125
|
-
expect {
|
3126
|
-
post.videos
|
3127
|
-
}.to raise_error(Mongoid::Errors::MixedRelations)
|
2493
|
+
it 'raises an error' do
|
2494
|
+
expect { post.videos }
|
2495
|
+
.to raise_error(Mongoid::Errors::MixedRelations)
|
3128
2496
|
end
|
3129
2497
|
end
|
3130
2498
|
|
3131
|
-
context
|
3132
|
-
|
3133
|
-
let(:post) do
|
3134
|
-
Post.new
|
3135
|
-
end
|
2499
|
+
context 'when a cyclic association exists' do
|
2500
|
+
let(:post) { Post.new }
|
3136
2501
|
|
3137
|
-
it
|
2502
|
+
it 'does not raise an error' do
|
3138
2503
|
expect(post.roles).to be_empty
|
3139
2504
|
end
|
3140
2505
|
end
|
3141
2506
|
end
|
3142
2507
|
|
3143
|
-
describe
|
3144
|
-
|
3145
|
-
let(:person) do
|
3146
|
-
Person.create!
|
3147
|
-
end
|
3148
|
-
|
3149
|
-
let!(:persisted_post) do
|
3150
|
-
person.posts.create!
|
3151
|
-
end
|
3152
|
-
|
3153
|
-
context "when a new document is added" do
|
2508
|
+
describe '#last' do
|
2509
|
+
let(:person) { Person.create! }
|
3154
2510
|
|
3155
|
-
|
3156
|
-
person.posts.new
|
3157
|
-
end
|
2511
|
+
before { person.posts.create! }
|
3158
2512
|
|
3159
|
-
|
2513
|
+
context 'when a new document is added' do
|
2514
|
+
let!(:new_post) { person.posts.new }
|
3160
2515
|
|
2516
|
+
context 'when the target is subsequently loaded' do
|
3161
2517
|
before do
|
3162
2518
|
person.posts.entries
|
3163
2519
|
end
|
3164
2520
|
|
3165
|
-
it
|
2521
|
+
it 'returns the expected last document' do
|
3166
2522
|
expect(person.posts.last).to eq(new_post)
|
3167
2523
|
end
|
3168
2524
|
end
|
3169
2525
|
end
|
3170
2526
|
end
|
3171
2527
|
|
3172
|
-
describe
|
3173
|
-
|
3174
|
-
let(:
|
3175
|
-
|
3176
|
-
end
|
3177
|
-
|
3178
|
-
let(:post_one) do
|
3179
|
-
Post.create!(rating: 5)
|
3180
|
-
end
|
2528
|
+
describe '#max' do
|
2529
|
+
let(:person) { Person.create! }
|
2530
|
+
let(:post_one) { Post.create!(rating: 5) }
|
2531
|
+
let(:post_two) { Post.create!(rating: 10) }
|
3181
2532
|
|
3182
|
-
|
3183
|
-
|
2533
|
+
# rubocop:disable Performance/CompareWithBlock
|
2534
|
+
let(:max) do
|
2535
|
+
person.posts.max do |a, b|
|
2536
|
+
a.rating <=> b.rating
|
2537
|
+
end
|
3184
2538
|
end
|
2539
|
+
# rubocop:enable Performance/CompareWithBlock
|
3185
2540
|
|
3186
2541
|
before do
|
3187
2542
|
person.posts.push(post_one, post_two)
|
3188
2543
|
end
|
3189
2544
|
|
3190
|
-
|
3191
|
-
person.posts.max do |a,b|
|
3192
|
-
a.rating <=> b.rating
|
3193
|
-
end
|
3194
|
-
end
|
3195
|
-
|
3196
|
-
it "returns the document with the max value of the supplied field" do
|
2545
|
+
it 'returns the document with the max value of the supplied field' do
|
3197
2546
|
expect(max).to eq(post_two)
|
3198
2547
|
end
|
3199
2548
|
end
|
3200
2549
|
|
3201
|
-
describe
|
3202
|
-
|
3203
|
-
let(:
|
3204
|
-
|
3205
|
-
|
3206
|
-
|
3207
|
-
let(:post_one) do
|
3208
|
-
Post.create!(rating: 5)
|
3209
|
-
end
|
3210
|
-
|
3211
|
-
let(:post_two) do
|
3212
|
-
Post.create!(rating: 10)
|
3213
|
-
end
|
2550
|
+
describe '#max_by' do
|
2551
|
+
let(:person) { Person.create! }
|
2552
|
+
let(:post_one) { Post.create!(rating: 5) }
|
2553
|
+
let(:post_two) { Post.create!(rating: 10) }
|
2554
|
+
let(:max) { person.posts.max_by(&:rating) }
|
3214
2555
|
|
3215
2556
|
before do
|
3216
2557
|
person.posts.push(post_one, post_two)
|
3217
2558
|
end
|
3218
2559
|
|
3219
|
-
|
3220
|
-
person.posts.max_by(&:rating)
|
3221
|
-
end
|
3222
|
-
|
3223
|
-
it "returns the document with the max value of the supplied field" do
|
2560
|
+
it 'returns the document with the max value of the supplied field' do
|
3224
2561
|
expect(max).to eq(post_two)
|
3225
2562
|
end
|
3226
2563
|
end
|
3227
2564
|
|
3228
|
-
describe
|
2565
|
+
describe '#method_missing' do
|
2566
|
+
let!(:person) { Person.create! }
|
2567
|
+
let!(:post_one) { person.posts.create!(title: 'First', content: 'Posting') }
|
3229
2568
|
|
3230
|
-
|
3231
|
-
|
3232
|
-
end
|
3233
|
-
|
3234
|
-
let!(:post_one) do
|
3235
|
-
person.posts.create!(title: "First", content: "Posting")
|
3236
|
-
end
|
3237
|
-
|
3238
|
-
let!(:post_two) do
|
3239
|
-
person.posts.create!(title: "Second", content: "Testing")
|
2569
|
+
before do
|
2570
|
+
person.posts.create!(title: 'Second', content: 'Testing')
|
3240
2571
|
end
|
3241
2572
|
|
3242
|
-
context
|
3243
|
-
|
3244
|
-
let(:posts) do
|
3245
|
-
person.posts.where(title: "First")
|
3246
|
-
end
|
2573
|
+
context 'when providing a single criteria' do
|
2574
|
+
let(:posts) { person.posts.where(title: 'First') }
|
3247
2575
|
|
3248
|
-
it
|
2576
|
+
it 'applies the criteria to the documents' do
|
3249
2577
|
expect(posts).to eq([ post_one ])
|
3250
2578
|
end
|
3251
2579
|
|
3252
2580
|
context 'when providing a collation' do
|
3253
|
-
|
2581
|
+
let(:posts) { person.posts.where(title: 'FIRST').collation(locale: 'en_US', strength: 2) }
|
3254
2582
|
|
3255
|
-
|
3256
|
-
person.posts.where(title: "FIRST").collation(locale: 'en_US', strength: 2)
|
3257
|
-
end
|
3258
|
-
|
3259
|
-
it "applies the collation option to the query" do
|
2583
|
+
it 'applies the collation option to the query' do
|
3260
2584
|
expect(posts).to eq([ post_one ])
|
3261
2585
|
end
|
3262
2586
|
end
|
3263
2587
|
end
|
3264
2588
|
|
3265
|
-
context
|
3266
|
-
|
3267
|
-
let(:posts) do
|
3268
|
-
person.posts.posting
|
3269
|
-
end
|
2589
|
+
context 'when providing a criteria class method' do
|
2590
|
+
let(:posts) { person.posts.posting }
|
3270
2591
|
|
3271
|
-
it
|
2592
|
+
it 'applies the criteria to the documents' do
|
3272
2593
|
expect(posts).to eq([ post_one ])
|
3273
2594
|
end
|
3274
2595
|
end
|
3275
2596
|
|
3276
|
-
context
|
2597
|
+
context 'when chaining criteria' do
|
2598
|
+
let(:posts) { person.posts.posting.where(:title.in => [ 'First' ]) }
|
3277
2599
|
|
3278
|
-
|
3279
|
-
person.posts.posting.where(:title.in => [ "First" ])
|
3280
|
-
end
|
3281
|
-
|
3282
|
-
it "applies the criteria to the documents" do
|
2600
|
+
it 'applies the criteria to the documents' do
|
3283
2601
|
expect(posts).to eq([ post_one ])
|
3284
2602
|
end
|
3285
2603
|
end
|
3286
2604
|
|
3287
|
-
context
|
3288
|
-
|
3289
|
-
|
3290
|
-
|
3291
|
-
let(:values) do
|
3292
|
-
person.posts.distinct(:title)
|
3293
|
-
end
|
2605
|
+
context 'when delegating methods' do
|
2606
|
+
describe '#distinct' do
|
2607
|
+
let(:values) { person.posts.distinct(:title) }
|
3294
2608
|
|
3295
|
-
it
|
3296
|
-
expect(values).to include(
|
3297
|
-
expect(values).to include(
|
2609
|
+
it 'returns the distinct values for the fields' do
|
2610
|
+
expect(values).to include('First')
|
2611
|
+
expect(values).to include('Second')
|
3298
2612
|
end
|
3299
2613
|
end
|
3300
2614
|
end
|
3301
2615
|
end
|
3302
2616
|
|
3303
|
-
describe
|
3304
|
-
|
3305
|
-
let(:
|
3306
|
-
|
3307
|
-
end
|
3308
|
-
|
3309
|
-
let(:post_one) do
|
3310
|
-
Post.create!(rating: 5)
|
3311
|
-
end
|
3312
|
-
|
3313
|
-
let(:post_two) do
|
3314
|
-
Post.create!(rating: 10)
|
3315
|
-
end
|
3316
|
-
|
3317
|
-
before do
|
3318
|
-
person.posts.push(post_one, post_two)
|
3319
|
-
end
|
2617
|
+
describe '#min' do
|
2618
|
+
let(:person) { Person.create! }
|
2619
|
+
let(:post_one) { Post.create!(rating: 5) }
|
2620
|
+
let(:post_two) { Post.create!(rating: 10) }
|
3320
2621
|
|
2622
|
+
# rubocop:disable Performance/CompareWithBlock
|
3321
2623
|
let(:min) do
|
3322
2624
|
person.posts.min do |a, b|
|
3323
2625
|
a.rating <=> b.rating
|
3324
2626
|
end
|
3325
2627
|
end
|
2628
|
+
# rubocop:enable Performance/CompareWithBlock
|
3326
2629
|
|
3327
|
-
|
3328
|
-
|
2630
|
+
before do
|
2631
|
+
person.posts.push(post_one, post_two)
|
3329
2632
|
end
|
3330
|
-
end
|
3331
2633
|
|
3332
|
-
|
3333
|
-
|
3334
|
-
let(:person) do
|
3335
|
-
Person.create!
|
2634
|
+
it 'returns the min value of the supplied field' do
|
2635
|
+
expect(min).to eq(post_one)
|
3336
2636
|
end
|
2637
|
+
end
|
3337
2638
|
|
3338
|
-
|
3339
|
-
|
3340
|
-
|
2639
|
+
describe '#min_by' do
|
2640
|
+
let(:person) { Person.create! }
|
2641
|
+
let(:post_one) { Post.create!(rating: 5) }
|
3341
2642
|
|
3342
|
-
let(:post_two)
|
3343
|
-
|
3344
|
-
end
|
2643
|
+
let(:post_two) { Post.create!(rating: 10) }
|
2644
|
+
let(:min) { person.posts.min_by(&:rating) }
|
3345
2645
|
|
3346
2646
|
before do
|
3347
2647
|
person.posts.push(post_one, post_two)
|
3348
2648
|
end
|
3349
2649
|
|
3350
|
-
|
3351
|
-
person.posts.min_by(&:rating)
|
3352
|
-
end
|
3353
|
-
|
3354
|
-
it "returns the min value of the supplied field" do
|
2650
|
+
it 'returns the min value of the supplied field' do
|
3355
2651
|
expect(min).to eq(post_one)
|
3356
2652
|
end
|
3357
2653
|
end
|
3358
2654
|
|
3359
|
-
describe
|
3360
|
-
|
3361
|
-
|
3362
|
-
|
3363
|
-
let(:person) do
|
3364
|
-
Person.create!
|
3365
|
-
end
|
3366
|
-
|
3367
|
-
let!(:post_one) do
|
3368
|
-
person.posts.create!(title: "One")
|
3369
|
-
end
|
3370
|
-
|
3371
|
-
let!(:post_two) do
|
3372
|
-
person.posts.create!(title: "Two")
|
3373
|
-
end
|
3374
|
-
|
3375
|
-
let(:from_db) do
|
3376
|
-
Person.first
|
3377
|
-
end
|
2655
|
+
describe '#nullify_all' do
|
2656
|
+
context 'when the inverse has not been loaded' do
|
2657
|
+
let(:person) { Person.create! }
|
2658
|
+
let(:from_db) { Person.first }
|
3378
2659
|
|
3379
2660
|
before do
|
2661
|
+
person.posts.create!(title: 'One')
|
2662
|
+
person.posts.create!(title: 'Two')
|
3380
2663
|
from_db.posts.nullify_all
|
3381
2664
|
end
|
3382
2665
|
|
3383
|
-
it
|
2666
|
+
it 'loads the targets before nullifying' do
|
3384
2667
|
expect(from_db.posts).to be_empty
|
3385
2668
|
end
|
3386
2669
|
|
3387
|
-
it
|
2670
|
+
it 'persists the base nullifications' do
|
3388
2671
|
expect(Person.first.posts).to be_empty
|
3389
2672
|
end
|
3390
2673
|
|
3391
|
-
it
|
2674
|
+
it 'persists the inverse nullifications' do
|
3392
2675
|
Post.all.each do |post|
|
3393
2676
|
expect(post.person).to be_nil
|
3394
2677
|
end
|
3395
2678
|
end
|
3396
2679
|
end
|
3397
2680
|
|
3398
|
-
context
|
3399
|
-
|
3400
|
-
let(:person)
|
3401
|
-
|
3402
|
-
end
|
3403
|
-
|
3404
|
-
let!(:post_one) do
|
3405
|
-
person.posts.create!(title: "One")
|
3406
|
-
end
|
3407
|
-
|
3408
|
-
let!(:post_two) do
|
3409
|
-
person.posts.create!(title: "Two")
|
3410
|
-
end
|
2681
|
+
context 'when the association is not polymorphic' do
|
2682
|
+
let(:person) { Person.create! }
|
2683
|
+
let!(:post_one) { person.posts.create!(title: 'One') }
|
2684
|
+
let!(:post_two) { person.posts.create!(title: 'Two') }
|
3411
2685
|
|
3412
2686
|
before do
|
3413
2687
|
person.posts.nullify_all
|
3414
2688
|
end
|
3415
2689
|
|
3416
|
-
it
|
2690
|
+
it 'removes all the foreign keys from the target' do
|
3417
2691
|
[ post_one, post_two ].each do |post|
|
3418
2692
|
expect(post.person_id).to be_nil
|
3419
2693
|
end
|
3420
2694
|
end
|
3421
2695
|
|
3422
|
-
it
|
2696
|
+
it 'removes all the references from the target' do
|
3423
2697
|
[ post_one, post_two ].each do |post|
|
3424
2698
|
expect(post.person).to be_nil
|
3425
2699
|
end
|
3426
2700
|
end
|
3427
2701
|
|
3428
|
-
it
|
2702
|
+
it 'saves the documents' do
|
3429
2703
|
expect(post_one.reload.person).to be_nil
|
3430
2704
|
end
|
3431
2705
|
|
3432
|
-
context
|
3433
|
-
|
2706
|
+
context 'when adding a nullified document back to the association' do
|
3434
2707
|
before do
|
3435
2708
|
person.posts.push(post_one)
|
3436
2709
|
end
|
3437
2710
|
|
3438
|
-
it
|
2711
|
+
it 'persists the association' do
|
3439
2712
|
expect(person.posts(true)).to eq([ post_one ])
|
3440
2713
|
end
|
3441
2714
|
end
|
3442
2715
|
end
|
3443
2716
|
|
3444
|
-
context
|
3445
|
-
|
3446
|
-
let(:movie)
|
3447
|
-
|
3448
|
-
end
|
3449
|
-
|
3450
|
-
let!(:rating_one) do
|
3451
|
-
movie.ratings.create!(value: 10)
|
3452
|
-
end
|
3453
|
-
|
3454
|
-
let!(:rating_two) do
|
3455
|
-
movie.ratings.create!(value: 9)
|
3456
|
-
end
|
2717
|
+
context 'when the association is polymorphic' do
|
2718
|
+
let(:movie) { Movie.create!(title: 'Oldboy') }
|
2719
|
+
let!(:rating_one) { movie.ratings.create!(value: 10) }
|
2720
|
+
let!(:rating_two) { movie.ratings.create!(value: 9) }
|
3457
2721
|
|
3458
2722
|
before do
|
3459
2723
|
movie.ratings.nullify_all
|
3460
2724
|
end
|
3461
2725
|
|
3462
|
-
it
|
2726
|
+
it 'removes all the foreign keys from the target' do
|
3463
2727
|
[ rating_one, rating_two ].each do |rating|
|
3464
2728
|
expect(rating.ratable_id).to be_nil
|
3465
2729
|
end
|
3466
2730
|
end
|
3467
2731
|
|
3468
|
-
it
|
2732
|
+
it 'removes all the references from the target' do
|
3469
2733
|
[ rating_one, rating_two ].each do |rating|
|
3470
2734
|
expect(rating.ratable).to be_nil
|
3471
2735
|
end
|
@@ -3473,443 +2737,323 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
3473
2737
|
end
|
3474
2738
|
end
|
3475
2739
|
|
3476
|
-
describe
|
3477
|
-
|
3478
|
-
let(:
|
3479
|
-
Person.new
|
3480
|
-
end
|
3481
|
-
|
3482
|
-
let(:posts) do
|
3483
|
-
person.posts
|
3484
|
-
end
|
2740
|
+
describe '#respond_to?' do
|
2741
|
+
let(:person) { Person.new }
|
2742
|
+
let(:posts) { person.posts }
|
3485
2743
|
|
3486
2744
|
Array.public_instance_methods.each do |method|
|
3487
|
-
|
3488
2745
|
context "when checking #{method}" do
|
3489
|
-
|
3490
|
-
it "returns true" do
|
2746
|
+
it 'returns true' do
|
3491
2747
|
expect(posts.respond_to?(method)).to be true
|
3492
2748
|
end
|
3493
2749
|
end
|
3494
2750
|
end
|
3495
2751
|
|
3496
|
-
|
3497
|
-
|
2752
|
+
described_class.public_instance_methods.each do |method|
|
3498
2753
|
context "when checking #{method}" do
|
3499
|
-
|
3500
|
-
it "returns true" do
|
2754
|
+
it 'returns true' do
|
3501
2755
|
expect(posts.respond_to?(method)).to be true
|
3502
2756
|
end
|
3503
2757
|
end
|
3504
2758
|
end
|
3505
2759
|
|
3506
|
-
Post.scopes.
|
3507
|
-
|
2760
|
+
Post.scopes.each_key do |method|
|
3508
2761
|
context "when checking #{method}" do
|
3509
|
-
|
3510
|
-
it "returns true" do
|
2762
|
+
it 'returns true' do
|
3511
2763
|
expect(posts.respond_to?(method)).to be true
|
3512
2764
|
end
|
3513
2765
|
end
|
3514
2766
|
end
|
3515
2767
|
end
|
3516
2768
|
|
3517
|
-
describe
|
3518
|
-
|
3519
|
-
let(:
|
3520
|
-
Person.new
|
3521
|
-
end
|
2769
|
+
describe '#scoped' do
|
2770
|
+
let(:person) { Person.new }
|
2771
|
+
let(:scoped) { person.posts.scoped }
|
3522
2772
|
|
3523
|
-
|
3524
|
-
person.posts.scoped
|
3525
|
-
end
|
3526
|
-
|
3527
|
-
it "returns the association criteria" do
|
2773
|
+
it 'returns the association criteria' do
|
3528
2774
|
expect(scoped).to be_a(Mongoid::Criteria)
|
3529
2775
|
end
|
3530
2776
|
|
3531
|
-
it
|
3532
|
-
expect(scoped.selector).to eq({
|
2777
|
+
it 'returns with an empty selector' do
|
2778
|
+
expect(scoped.selector).to eq({ 'person_id' => person.id })
|
3533
2779
|
end
|
3534
2780
|
end
|
3535
2781
|
|
3536
|
-
[
|
3537
|
-
|
2782
|
+
%i[ size length ].each do |method|
|
3538
2783
|
describe "##{method}" do
|
2784
|
+
let(:movie) { Movie.create! }
|
3539
2785
|
|
3540
|
-
|
3541
|
-
|
3542
|
-
end
|
3543
|
-
|
3544
|
-
context "when documents have been persisted" do
|
3545
|
-
|
3546
|
-
let!(:rating) do
|
2786
|
+
context 'when documents have been persisted' do
|
2787
|
+
before do
|
3547
2788
|
movie.ratings.create!(value: 1)
|
3548
2789
|
end
|
3549
2790
|
|
3550
|
-
it
|
2791
|
+
it 'returns 1' do
|
3551
2792
|
expect(movie.ratings.send(method)).to eq(1)
|
3552
2793
|
end
|
3553
2794
|
end
|
3554
2795
|
|
3555
|
-
context
|
3556
|
-
|
2796
|
+
context 'when documents have not been persisted' do
|
3557
2797
|
before do
|
3558
2798
|
movie.ratings.build(value: 1)
|
3559
2799
|
movie.ratings.create!(value: 2)
|
3560
2800
|
end
|
3561
2801
|
|
3562
|
-
it
|
2802
|
+
it 'returns the total number of documents' do
|
3563
2803
|
expect(movie.ratings.send(method)).to eq(2)
|
3564
2804
|
end
|
3565
2805
|
end
|
3566
2806
|
end
|
3567
2807
|
end
|
3568
2808
|
|
3569
|
-
describe
|
3570
|
-
|
3571
|
-
|
2809
|
+
describe '#unscoped' do
|
2810
|
+
context 'when the association has no default scope' do
|
2811
|
+
before { Post.create!(title: 'unattributed') }
|
3572
2812
|
|
3573
|
-
let!(:person)
|
3574
|
-
|
3575
|
-
|
2813
|
+
let!(:person) { Person.create! }
|
2814
|
+
let!(:post_one) { person.posts.create!(title: 'first') }
|
2815
|
+
let(:unscoped) { person.posts.unscoped }
|
3576
2816
|
|
3577
|
-
|
3578
|
-
person.posts.create!(title: "first")
|
3579
|
-
end
|
3580
|
-
|
3581
|
-
let!(:post_two) do
|
3582
|
-
Post.create!(title: "second")
|
3583
|
-
end
|
3584
|
-
|
3585
|
-
let(:unscoped) do
|
3586
|
-
person.posts.unscoped
|
3587
|
-
end
|
3588
|
-
|
3589
|
-
it "returns only the associated documents" do
|
2817
|
+
it 'returns only the associated documents' do
|
3590
2818
|
expect(unscoped).to eq([ post_one ])
|
3591
2819
|
end
|
3592
2820
|
end
|
3593
2821
|
|
3594
|
-
context
|
3595
|
-
|
3596
|
-
let!(:church) do
|
3597
|
-
Church.create!
|
3598
|
-
end
|
3599
|
-
|
3600
|
-
let!(:acolyte_one) do
|
3601
|
-
church.acolytes.create!(name: "first")
|
3602
|
-
end
|
3603
|
-
|
3604
|
-
let!(:acolyte_two) do
|
3605
|
-
Acolyte.create!(name: "second")
|
3606
|
-
end
|
2822
|
+
context 'when the association has a default scope' do
|
2823
|
+
before { Acolyte.create!(name: 'unaffiliated') }
|
3607
2824
|
|
3608
|
-
let(:
|
3609
|
-
|
3610
|
-
|
2825
|
+
let!(:church) { Church.create! }
|
2826
|
+
let!(:acolyte_one) { church.acolytes.create!(name: 'first') }
|
2827
|
+
let(:unscoped) { church.acolytes.unscoped }
|
3611
2828
|
|
3612
|
-
it
|
2829
|
+
it 'only returns associated documents' do
|
3613
2830
|
expect(unscoped).to eq([ acolyte_one ])
|
3614
2831
|
end
|
3615
2832
|
|
3616
|
-
it
|
2833
|
+
it 'removes the default scoping options' do
|
3617
2834
|
expect(unscoped.options).to eq({})
|
3618
2835
|
end
|
3619
2836
|
end
|
3620
2837
|
end
|
3621
2838
|
|
3622
|
-
context
|
3623
|
-
|
3624
|
-
let(:
|
3625
|
-
Person.create!
|
3626
|
-
end
|
3627
|
-
|
3628
|
-
let(:post_one) do
|
3629
|
-
OrderedPost.create!(rating: 10, title: '1')
|
3630
|
-
end
|
3631
|
-
|
3632
|
-
let(:post_two) do
|
3633
|
-
OrderedPost.create!(rating: 20, title: '2')
|
3634
|
-
end
|
2839
|
+
context 'when the association has an order defined' do
|
2840
|
+
let(:person) { Person.create! }
|
2841
|
+
let(:post_one) { OrderedPost.create!(rating: 10, title: '1') }
|
3635
2842
|
|
3636
|
-
let(:
|
3637
|
-
|
3638
|
-
end
|
2843
|
+
let(:post_two) { OrderedPost.create!(rating: 20, title: '2') }
|
2844
|
+
let(:post_three) { OrderedPost.create!(rating: 20, title: '3') }
|
3639
2845
|
|
3640
2846
|
before do
|
3641
2847
|
person.ordered_posts.nullify_all
|
3642
2848
|
person.ordered_posts.push(post_one, post_two, post_three)
|
3643
2849
|
end
|
3644
2850
|
|
3645
|
-
it
|
3646
|
-
expect(person.ordered_posts(true))
|
3647
|
-
|
3648
|
-
)
|
2851
|
+
it 'order documents' do
|
2852
|
+
expect(person.ordered_posts(true))
|
2853
|
+
.to eq [ post_two, post_three, post_one ]
|
3649
2854
|
end
|
3650
2855
|
|
3651
|
-
it
|
3652
|
-
expect(person.ordered_posts.order_by(:title.desc).to_a)
|
3653
|
-
|
3654
|
-
)
|
2856
|
+
it 'chaining order criteria' do
|
2857
|
+
expect(person.ordered_posts.order_by(:title.desc).to_a)
|
2858
|
+
.to eq [ post_three, post_two, post_one ]
|
3655
2859
|
end
|
3656
2860
|
end
|
3657
2861
|
|
3658
|
-
context
|
2862
|
+
context 'when reloading the association' do
|
2863
|
+
let!(:person) { Person.create! }
|
2864
|
+
let!(:post_one) { Post.create!(title: 'one') }
|
3659
2865
|
|
3660
|
-
let!(:
|
3661
|
-
Person.create!
|
3662
|
-
end
|
3663
|
-
|
3664
|
-
let!(:post_one) do
|
3665
|
-
Post.create!(title: "one")
|
3666
|
-
end
|
3667
|
-
|
3668
|
-
let!(:post_two) do
|
3669
|
-
Post.create!(title: "two")
|
3670
|
-
end
|
2866
|
+
let!(:post_two) { Post.create!(title: 'two') }
|
3671
2867
|
|
3672
2868
|
before do
|
3673
2869
|
person.posts << post_one
|
3674
2870
|
end
|
3675
2871
|
|
3676
|
-
context
|
3677
|
-
|
2872
|
+
context 'when the association references the same documents' do
|
3678
2873
|
before do
|
3679
|
-
Post.collection.find({ _id: post_one.id })
|
3680
|
-
update_one({
|
2874
|
+
Post.collection.find({ _id: post_one.id })
|
2875
|
+
.update_one({ '$set' => { title: 'reloaded' } })
|
3681
2876
|
end
|
3682
2877
|
|
3683
|
-
let(:reloaded)
|
3684
|
-
person.posts(true)
|
3685
|
-
end
|
2878
|
+
let(:reloaded) { person.posts(true) }
|
3686
2879
|
|
3687
|
-
it
|
3688
|
-
expect(reloaded.first.title).to eq(
|
2880
|
+
it 'reloads the document from the database' do
|
2881
|
+
expect(reloaded.first.title).to eq('reloaded')
|
3689
2882
|
end
|
3690
2883
|
end
|
3691
2884
|
|
3692
|
-
context
|
3693
|
-
|
2885
|
+
context 'when the association references different documents' do
|
3694
2886
|
before do
|
3695
2887
|
person.posts << post_two
|
3696
2888
|
end
|
3697
2889
|
|
3698
|
-
let(:reloaded)
|
3699
|
-
person.posts(true)
|
3700
|
-
end
|
2890
|
+
let(:reloaded) { person.posts(true) }
|
3701
2891
|
|
3702
|
-
it
|
2892
|
+
it 'reloads the first document from the database' do
|
3703
2893
|
expect(reloaded).to include(post_one)
|
3704
2894
|
end
|
3705
2895
|
|
3706
|
-
it
|
2896
|
+
it 'reloads the new document from the database' do
|
3707
2897
|
expect(reloaded).to include(post_two)
|
3708
2898
|
end
|
3709
2899
|
end
|
3710
2900
|
end
|
3711
2901
|
|
3712
|
-
context
|
3713
|
-
|
2902
|
+
context 'when the parent is using integer ids' do
|
3714
2903
|
let(:jar) do
|
3715
2904
|
Jar.create! do |doc|
|
3716
2905
|
doc._id = 1
|
3717
2906
|
end
|
3718
2907
|
end
|
3719
2908
|
|
3720
|
-
it
|
2909
|
+
it 'allows creation of the document' do
|
3721
2910
|
expect(jar.id).to eq(1)
|
3722
2911
|
end
|
3723
2912
|
end
|
3724
2913
|
|
3725
|
-
context
|
2914
|
+
context 'when adding a document' do
|
2915
|
+
let(:person) { Person.new }
|
2916
|
+
let(:post_one) { Post.new }
|
2917
|
+
let(:first_add) { person.posts.push(post_one) }
|
3726
2918
|
|
3727
|
-
|
3728
|
-
|
3729
|
-
|
2919
|
+
context 'when chaining a second add' do
|
2920
|
+
let(:post_two) { Post.new }
|
2921
|
+
let(:result) { first_add.push(post_two) }
|
3730
2922
|
|
3731
|
-
|
3732
|
-
Post.new
|
3733
|
-
end
|
3734
|
-
|
3735
|
-
let(:first_add) do
|
3736
|
-
person.posts.push(post_one)
|
3737
|
-
end
|
3738
|
-
|
3739
|
-
context "when chaining a second add" do
|
3740
|
-
|
3741
|
-
let(:post_two) do
|
3742
|
-
Post.new
|
3743
|
-
end
|
3744
|
-
|
3745
|
-
let(:result) do
|
3746
|
-
first_add.push(post_two)
|
3747
|
-
end
|
3748
|
-
|
3749
|
-
it "adds both documents" do
|
2923
|
+
it 'adds both documents' do
|
3750
2924
|
expect(result).to eq([ post_one, post_two ])
|
3751
2925
|
end
|
3752
2926
|
end
|
3753
2927
|
end
|
3754
2928
|
|
3755
|
-
context
|
3756
|
-
|
3757
|
-
let(:
|
3758
|
-
Artist.new
|
3759
|
-
end
|
3760
|
-
|
3761
|
-
let(:album) do
|
3762
|
-
Album.new
|
3763
|
-
end
|
3764
|
-
|
3765
|
-
context "when execution raises no errors" do
|
2929
|
+
context 'when pushing with a before_add callback' do
|
2930
|
+
let(:artist) { Artist.new }
|
2931
|
+
let(:album) { Album.new }
|
3766
2932
|
|
2933
|
+
context 'when execution raises no errors' do
|
3767
2934
|
before do
|
3768
2935
|
artist.albums << album
|
3769
2936
|
end
|
3770
2937
|
|
3771
|
-
it
|
2938
|
+
it 'executes method callbacks' do
|
3772
2939
|
expect(artist.before_add_referenced_called).to be true
|
3773
2940
|
end
|
3774
2941
|
|
3775
|
-
it
|
2942
|
+
it 'executes proc callbacks' do
|
3776
2943
|
expect(album.before_add_called).to be true
|
3777
2944
|
end
|
3778
2945
|
|
3779
|
-
it
|
2946
|
+
it 'adds the document to the association' do
|
3780
2947
|
expect(artist.albums).to eq([ album ])
|
3781
2948
|
end
|
3782
2949
|
end
|
3783
2950
|
|
3784
|
-
context
|
3785
|
-
|
2951
|
+
context 'when execution raises errors' do
|
3786
2952
|
before do
|
3787
|
-
|
3788
|
-
begin; artist.albums << album; rescue; end
|
2953
|
+
allow(artist).to receive(:before_add_album).and_raise
|
3789
2954
|
end
|
3790
2955
|
|
3791
|
-
it
|
2956
|
+
it 'does not add the document to the association' do
|
2957
|
+
expect { artist.albums << album }.to raise_error(StandardError)
|
3792
2958
|
expect(artist.albums).to be_empty
|
3793
2959
|
end
|
3794
2960
|
end
|
3795
2961
|
end
|
3796
2962
|
|
3797
|
-
context
|
2963
|
+
context 'when pushing with an after_add callback' do
|
2964
|
+
let(:artist) { Artist.new }
|
2965
|
+
let(:album) { Album.new }
|
3798
2966
|
|
3799
|
-
|
3800
|
-
Artist.new
|
3801
|
-
end
|
3802
|
-
|
3803
|
-
let(:album) do
|
3804
|
-
Album.new
|
3805
|
-
end
|
3806
|
-
|
3807
|
-
it "executes the callback" do
|
2967
|
+
it 'executes the callback' do
|
3808
2968
|
artist.albums << album
|
3809
2969
|
expect(artist.after_add_referenced_called).to be true
|
3810
2970
|
end
|
3811
2971
|
|
3812
|
-
context
|
3813
|
-
|
2972
|
+
context 'when execution raises errors' do
|
3814
2973
|
before do
|
3815
|
-
|
3816
|
-
begin; artist.albums << album; rescue; end
|
2974
|
+
allow(artist).to receive(:after_add_album).and_raise
|
3817
2975
|
end
|
3818
2976
|
|
3819
|
-
it
|
2977
|
+
it 'adds the document to the association' do
|
2978
|
+
expect { artist.albums << album }.to raise_error(StandardError)
|
3820
2979
|
expect(artist.albums).to eq([ album ])
|
3821
2980
|
end
|
3822
2981
|
end
|
3823
2982
|
|
3824
2983
|
context 'when the association already exists' do
|
3825
|
-
|
3826
2984
|
before do
|
3827
2985
|
artist.albums << album
|
3828
2986
|
album.save!
|
3829
2987
|
artist.save!
|
3830
|
-
expect(artist).not_to receive(:after_add_album)
|
3831
2988
|
end
|
3832
2989
|
|
3833
2990
|
let(:reloaded_album) do
|
3834
|
-
Album.where(artist_id: artist.id).first
|
2991
|
+
Album.where(artist_id: artist.id).first.tap do |a|
|
2992
|
+
allow(a.artist).to receive(:after_add_album)
|
2993
|
+
end
|
3835
2994
|
end
|
3836
2995
|
|
2996
|
+
let(:reloaded_album_artist) { reloaded_album.artist }
|
2997
|
+
|
3837
2998
|
it 'does not execute the callback when the association is accessed' do
|
3838
|
-
expect(
|
2999
|
+
expect(reloaded_album_artist.after_add_referenced_called).to be_nil
|
3000
|
+
expect(reloaded_album_artist).not_to have_received(:after_add_album)
|
3839
3001
|
end
|
3840
3002
|
end
|
3841
3003
|
end
|
3842
3004
|
|
3843
|
-
context
|
3844
|
-
|
3845
|
-
let(:
|
3846
|
-
Artist.new
|
3847
|
-
end
|
3848
|
-
|
3849
|
-
let(:album) do
|
3850
|
-
Album.new
|
3851
|
-
end
|
3005
|
+
context 'when #delete or #clear with before_remove callback' do
|
3006
|
+
let(:artist) { Artist.new }
|
3007
|
+
let(:album) { Album.new }
|
3852
3008
|
|
3853
3009
|
before do
|
3854
3010
|
artist.albums << album
|
3855
3011
|
end
|
3856
3012
|
|
3857
|
-
context
|
3858
|
-
|
3859
|
-
describe "#delete" do
|
3860
|
-
|
3013
|
+
context 'when executing raises no errors' do
|
3014
|
+
describe '#delete' do
|
3861
3015
|
before do
|
3862
3016
|
artist.albums.delete album
|
3863
3017
|
end
|
3864
3018
|
|
3865
|
-
it
|
3019
|
+
it 'executes the callback' do
|
3866
3020
|
expect(artist.before_remove_referenced_called).to be true
|
3867
3021
|
end
|
3868
3022
|
|
3869
|
-
it
|
3023
|
+
it 'removes the document from the association' do
|
3870
3024
|
expect(artist.albums).to be_empty
|
3871
3025
|
end
|
3872
3026
|
end
|
3873
3027
|
|
3874
|
-
describe
|
3875
|
-
|
3028
|
+
describe '#clear' do
|
3876
3029
|
before do
|
3877
3030
|
artist.albums.clear
|
3878
3031
|
end
|
3879
3032
|
|
3880
|
-
it
|
3033
|
+
it 'executes the callback' do
|
3881
3034
|
expect(artist.before_remove_referenced_called).to be true
|
3882
3035
|
end
|
3883
3036
|
|
3884
|
-
it
|
3037
|
+
it 'clears the association' do
|
3885
3038
|
expect(artist.albums).to be_empty
|
3886
3039
|
end
|
3887
3040
|
end
|
3888
3041
|
|
3889
|
-
context
|
3890
|
-
|
3042
|
+
context 'when execution raises errors' do
|
3891
3043
|
before do
|
3892
|
-
|
3044
|
+
allow(artist).to receive(:before_remove_album).and_raise
|
3893
3045
|
end
|
3894
3046
|
|
3895
|
-
describe
|
3896
|
-
|
3897
|
-
|
3898
|
-
begin; artist.albums.delete(album); rescue; end
|
3899
|
-
end
|
3900
|
-
|
3901
|
-
it "does not remove the document from the association" do
|
3047
|
+
describe '#delete' do
|
3048
|
+
it 'does not remove the document from the association' do
|
3049
|
+
expect { artist.albums.delete(album) }.to raise_error(StandardError)
|
3902
3050
|
expect(artist.albums).to eq([ album ])
|
3903
3051
|
end
|
3904
3052
|
end
|
3905
3053
|
|
3906
|
-
describe
|
3907
|
-
|
3908
|
-
|
3909
|
-
begin; artist.albums.clear; rescue; end
|
3910
|
-
end
|
3911
|
-
|
3912
|
-
it "does not clear the association" do
|
3054
|
+
describe '#clear' do
|
3055
|
+
it 'does not clear the association' do
|
3056
|
+
expect { artist.albums.clear }.to raise_error(StandardError)
|
3913
3057
|
expect(artist.albums).to eq([ album ])
|
3914
3058
|
end
|
3915
3059
|
end
|
@@ -3917,130 +3061,83 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
3917
3061
|
end
|
3918
3062
|
end
|
3919
3063
|
|
3920
|
-
context
|
3921
|
-
|
3922
|
-
let(:
|
3923
|
-
Artist.new
|
3924
|
-
end
|
3925
|
-
|
3926
|
-
let(:album) do
|
3927
|
-
Album.new
|
3928
|
-
end
|
3064
|
+
context 'when #delete or #clear with after_remove callback' do
|
3065
|
+
let(:artist) { Artist.new }
|
3066
|
+
let(:album) { Album.new }
|
3929
3067
|
|
3930
3068
|
before do
|
3931
3069
|
artist.albums << album
|
3932
3070
|
end
|
3933
3071
|
|
3934
|
-
context
|
3935
|
-
|
3936
|
-
|
3937
|
-
|
3938
|
-
before do
|
3939
|
-
artist.albums.delete album
|
3940
|
-
end
|
3941
|
-
|
3942
|
-
it "executes the callback" do
|
3072
|
+
context 'without errors' do
|
3073
|
+
describe '#delete' do
|
3074
|
+
it 'executes the callback' do
|
3075
|
+
expect { artist.albums.delete album }.not_to raise_error
|
3943
3076
|
expect(artist.after_remove_referenced_called).to be true
|
3944
3077
|
end
|
3945
3078
|
end
|
3946
3079
|
|
3947
|
-
describe
|
3948
|
-
|
3949
|
-
|
3950
|
-
artist.albums.clear
|
3951
|
-
end
|
3952
|
-
|
3953
|
-
it "executes the callback" do
|
3954
|
-
artist.albums.clear
|
3080
|
+
describe '#clear' do
|
3081
|
+
it 'executes the callback' do
|
3082
|
+
expect { artist.albums.clear }.not_to raise_error
|
3955
3083
|
expect(artist.after_remove_referenced_called).to be true
|
3956
3084
|
end
|
3957
3085
|
end
|
3958
3086
|
end
|
3959
3087
|
|
3960
|
-
context
|
3961
|
-
|
3088
|
+
context 'when errors are raised' do
|
3962
3089
|
before do
|
3963
|
-
|
3090
|
+
allow(artist).to receive(:after_remove_album).and_raise
|
3964
3091
|
end
|
3965
3092
|
|
3966
|
-
describe
|
3967
|
-
|
3968
|
-
|
3969
|
-
begin; artist.albums.delete(album); rescue; end
|
3970
|
-
end
|
3971
|
-
|
3972
|
-
it "removes the documents from the association" do
|
3093
|
+
describe '#delete' do
|
3094
|
+
it 'removes the documents from the association' do
|
3095
|
+
expect { artist.albums.delete(album) }.to raise_error(StandardError)
|
3973
3096
|
expect(artist.albums).to be_empty
|
3974
3097
|
end
|
3975
3098
|
end
|
3976
3099
|
|
3977
|
-
describe
|
3978
|
-
|
3979
|
-
|
3980
|
-
begin; artist.albums.clear; rescue; end
|
3981
|
-
end
|
3982
|
-
|
3983
|
-
it "removes the documents from the association" do
|
3100
|
+
describe '#clear' do
|
3101
|
+
it 'removes the documents from the association' do
|
3102
|
+
expect { artist.albums.clear }.to raise_error(StandardError)
|
3984
3103
|
expect(artist.albums).to be_empty
|
3985
3104
|
end
|
3986
3105
|
end
|
3987
3106
|
end
|
3988
3107
|
end
|
3989
3108
|
|
3990
|
-
context
|
3991
|
-
|
3992
|
-
let(:person)
|
3993
|
-
Person.create!
|
3994
|
-
end
|
3995
|
-
|
3996
|
-
let!(:post_one) do
|
3997
|
-
person.ordered_posts.create!(rating: 1)
|
3998
|
-
end
|
3999
|
-
|
4000
|
-
let!(:post_two) do
|
4001
|
-
person.ordered_posts.create!(rating: 5)
|
4002
|
-
end
|
3109
|
+
context 'when executing a criteria call on an ordered association' do
|
3110
|
+
let(:person) { Person.create! }
|
3111
|
+
let!(:post_one) { person.ordered_posts.create!(rating: 1) }
|
4003
3112
|
|
4004
|
-
let(:
|
4005
|
-
|
4006
|
-
end
|
3113
|
+
let!(:post_two) { person.ordered_posts.create!(rating: 5) }
|
3114
|
+
let(:criteria) { person.ordered_posts.only(:_id, :rating) }
|
4007
3115
|
|
4008
|
-
it
|
3116
|
+
it 'does not drop the ordering' do
|
4009
3117
|
expect(criteria).to eq([ post_two, post_one ])
|
4010
3118
|
end
|
4011
3119
|
end
|
4012
3120
|
|
4013
|
-
context
|
4014
|
-
|
4015
|
-
let(:person)
|
4016
|
-
Person.create!
|
4017
|
-
end
|
4018
|
-
|
4019
|
-
let!(:post) do
|
4020
|
-
person.posts.create!(title: "open")
|
4021
|
-
end
|
3121
|
+
context 'when accessing a scope named open' do
|
3122
|
+
let(:person) { Person.create! }
|
3123
|
+
let!(:post) { person.posts.create!(title: 'open') }
|
4022
3124
|
|
4023
|
-
it
|
3125
|
+
it 'returns the appropriate documents' do
|
4024
3126
|
expect(person.posts.open).to eq([ post ])
|
4025
3127
|
end
|
4026
3128
|
end
|
4027
3129
|
|
4028
|
-
context
|
4029
|
-
|
4030
|
-
let!(:parent) do
|
4031
|
-
Odd.create!(name: "odd parent")
|
4032
|
-
end
|
4033
|
-
|
3130
|
+
context 'when accessing a association named parent' do
|
3131
|
+
let!(:parent) { Odd.create!(name: 'odd parent') }
|
4034
3132
|
let(:child) do
|
4035
|
-
Even
|
3133
|
+
Even
|
3134
|
+
.create!(parent_id: parent.id, name: 'original even child')
|
3135
|
+
.tap(&:parent) # preload the parent association
|
4036
3136
|
end
|
4037
3137
|
|
4038
|
-
|
4039
|
-
# Access parent association on the child to make sure it is loaded
|
4040
|
-
child.parent
|
4041
|
-
|
4042
|
-
new_child_name = "updated even child"
|
3138
|
+
let(:new_child_name) { 'updated even child' }
|
4043
3139
|
|
3140
|
+
it 'updates the child after accessing the parent' do
|
4044
3141
|
child.name = new_child_name
|
4045
3142
|
child.save!
|
4046
3143
|
|
@@ -4050,18 +3147,10 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
4050
3147
|
end
|
4051
3148
|
|
4052
3149
|
context 'when a document has referenced and embedded associations' do
|
3150
|
+
let(:agent) { Agent.new }
|
3151
|
+
let(:basic) { Basic.new }
|
4053
3152
|
|
4054
|
-
let(:
|
4055
|
-
Agent.new
|
4056
|
-
end
|
4057
|
-
|
4058
|
-
let(:basic) do
|
4059
|
-
Basic.new
|
4060
|
-
end
|
4061
|
-
|
4062
|
-
let(:address) do
|
4063
|
-
Address.new
|
4064
|
-
end
|
3153
|
+
let(:address) { Address.new }
|
4065
3154
|
|
4066
3155
|
before do
|
4067
3156
|
agent.basics << basic
|
@@ -4074,14 +3163,8 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
4074
3163
|
end
|
4075
3164
|
|
4076
3165
|
context 'when the two models use the same name to refer to the association' do
|
4077
|
-
|
4078
|
-
let(:
|
4079
|
-
Agent.new
|
4080
|
-
end
|
4081
|
-
|
4082
|
-
let(:band) do
|
4083
|
-
Band.new
|
4084
|
-
end
|
3166
|
+
let(:agent) { Agent.new }
|
3167
|
+
let(:band) { Band.new }
|
4085
3168
|
|
4086
3169
|
before do
|
4087
3170
|
agent.same_name = band
|
@@ -4091,60 +3174,60 @@ describe Mongoid::Association::Referenced::HasMany::Proxy do
|
|
4091
3174
|
end
|
4092
3175
|
|
4093
3176
|
it 'constructs the correct criteria' do
|
4094
|
-
expect(band.same_name).to eq
|
3177
|
+
expect(band.same_name).to eq [ agent ]
|
4095
3178
|
end
|
4096
3179
|
end
|
4097
3180
|
|
4098
|
-
context
|
3181
|
+
context 'when updating a document with counter_cache on' do
|
4099
3182
|
let(:post) { Post.create! }
|
4100
|
-
let(:
|
4101
|
-
let(:
|
3183
|
+
let(:arthur) { Person.create! }
|
3184
|
+
let(:betty) { Person.create! }
|
4102
3185
|
|
4103
|
-
|
4104
|
-
|
4105
|
-
|
4106
|
-
|
4107
|
-
|
4108
|
-
post.update_attribute(:person, person2)
|
4109
|
-
person1.reload
|
4110
|
-
expect(person1.posts_count).to eq 0
|
4111
|
-
expect(person2.posts_count).to eq 1
|
4112
|
-
|
4113
|
-
post.update_attribute(:person, nil)
|
4114
|
-
person1.reload
|
4115
|
-
person2.reload
|
3186
|
+
context 'when setting an attribution' do
|
3187
|
+
it 'sets the counter correctly' do
|
3188
|
+
post.update_attribute(:person, arthur)
|
3189
|
+
expect(arthur.reload.posts_count).to eq 1
|
3190
|
+
end
|
4116
3191
|
end
|
4117
3192
|
|
4118
|
-
|
4119
|
-
|
3193
|
+
context 'when changing an attribution' do
|
3194
|
+
it 'sets the counter correctly' do
|
3195
|
+
post.update_attribute(:person, arthur)
|
3196
|
+
post.update_attribute(:person, betty)
|
3197
|
+
expect(arthur.reload.posts_count).to eq 0
|
3198
|
+
expect(betty.reload.posts_count).to eq 1
|
3199
|
+
end
|
4120
3200
|
end
|
4121
|
-
end
|
4122
3201
|
|
4123
|
-
|
4124
|
-
|
4125
|
-
|
4126
|
-
|
4127
|
-
|
3202
|
+
context 'when removing an attribution' do
|
3203
|
+
it 'sets the counter correctly' do
|
3204
|
+
post.update_attribute(:person, arthur)
|
3205
|
+
post.update_attribute(:person, nil)
|
3206
|
+
expect(arthur.reload.posts_count).to eq 0
|
3207
|
+
end
|
4128
3208
|
end
|
4129
3209
|
end
|
4130
3210
|
|
4131
|
-
context
|
4132
|
-
|
3211
|
+
context 'when there is a foreign key in the aliased associations' do
|
3212
|
+
it 'has the correct aliases' do
|
3213
|
+
expect(Band.aliased_associations['artist_ids']).to eq('artists')
|
3214
|
+
expect(Artist.aliased_associations.key?('band_id')).to be false
|
3215
|
+
expect(Artist.aliased_fields['band']).to eq('band_id')
|
3216
|
+
end
|
3217
|
+
end
|
4133
3218
|
|
3219
|
+
context 'when executing concat on foreign key array from the db' do
|
4134
3220
|
before do
|
4135
3221
|
Agent.create!
|
4136
3222
|
Basic.create!
|
3223
|
+
agent.basic_ids.push basic.id
|
4137
3224
|
end
|
4138
3225
|
|
4139
3226
|
let!(:agent) { Agent.first }
|
4140
3227
|
let!(:basic) { Basic.first }
|
4141
3228
|
|
4142
|
-
|
4143
|
-
agent.basic_ids.
|
4144
|
-
end
|
4145
|
-
|
4146
|
-
it "works on the first attempt" do
|
4147
|
-
expect(agent.basic_ids).to eq([basic.id])
|
3229
|
+
it 'works on the first attempt' do
|
3230
|
+
expect(agent.basic_ids).to eq [ basic.id ]
|
4148
3231
|
end
|
4149
3232
|
end
|
4150
3233
|
end
|