mongoid 3.1.6 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +479 -8
- data/README.md +10 -7
- data/lib/config/locales/en.yml +34 -20
- data/lib/mongoid.rb +10 -76
- data/lib/mongoid/atomic.rb +3 -14
- data/lib/mongoid/atomic/paths/embedded.rb +0 -30
- data/lib/mongoid/atomic/paths/embedded/many.rb +1 -1
- data/lib/mongoid/atomic/paths/embedded/one.rb +1 -1
- data/lib/mongoid/atomic/paths/root.rb +0 -13
- data/lib/mongoid/attributes.rb +65 -101
- data/lib/mongoid/attributes/dynamic.rb +154 -0
- data/lib/mongoid/attributes/nested.rb +82 -0
- data/lib/mongoid/attributes/processing.rb +13 -66
- data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
- data/lib/mongoid/composable.rb +105 -0
- data/lib/mongoid/config.rb +3 -9
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/contextual.rb +2 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +2 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +7 -9
- data/lib/mongoid/contextual/atomic.rb +53 -53
- data/lib/mongoid/contextual/geo_near.rb +1 -1
- data/lib/mongoid/contextual/map_reduce.rb +4 -2
- data/lib/mongoid/contextual/memory.rb +23 -11
- data/lib/mongoid/contextual/mongo.rb +75 -57
- data/lib/mongoid/contextual/none.rb +90 -0
- data/lib/mongoid/contextual/text_search.rb +178 -0
- data/lib/mongoid/copyable.rb +2 -3
- data/lib/mongoid/criteria.rb +39 -34
- data/lib/mongoid/criteria/#findable.rb# +141 -0
- data/lib/mongoid/{criterion → criteria}/findable.rb +7 -47
- data/lib/mongoid/{criterion/inspection.rb → criteria/inspectable.rb} +2 -2
- data/lib/mongoid/{criterion → criteria}/marshalable.rb +3 -1
- data/lib/mongoid/{criterion → criteria}/modifiable.rb +28 -8
- data/lib/mongoid/criteria/permission.rb +70 -0
- data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
- data/lib/mongoid/document.rb +39 -24
- data/lib/mongoid/errors.rb +4 -1
- data/lib/mongoid/errors/document_not_destroyed.rb +25 -0
- data/lib/mongoid/errors/document_not_found.rb +2 -1
- data/lib/mongoid/errors/invalid_storage_options.rb +1 -1
- data/lib/mongoid/errors/invalid_storage_parent.rb +26 -0
- data/lib/mongoid/errors/invalid_value.rb +16 -0
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/errors/readonly_document.rb +24 -0
- data/lib/mongoid/extensions.rb +15 -7
- data/lib/mongoid/extensions/array.rb +3 -3
- data/lib/mongoid/extensions/big_decimal.rb +1 -1
- data/lib/mongoid/extensions/boolean.rb +15 -17
- data/lib/mongoid/extensions/date.rb +1 -1
- data/lib/mongoid/extensions/date_time.rb +3 -3
- data/lib/mongoid/extensions/float.rb +2 -1
- data/lib/mongoid/extensions/hash.rb +3 -3
- data/lib/mongoid/extensions/integer.rb +1 -1
- data/lib/mongoid/extensions/object.rb +7 -7
- data/lib/mongoid/extensions/object_id.rb +5 -5
- data/lib/mongoid/extensions/range.rb +9 -3
- data/lib/mongoid/extensions/regexp.rb +1 -1
- data/lib/mongoid/extensions/set.rb +1 -1
- data/lib/mongoid/extensions/string.rb +6 -18
- data/lib/mongoid/extensions/symbol.rb +1 -1
- data/lib/mongoid/extensions/time.rb +3 -3
- data/lib/mongoid/extensions/time_with_zone.rb +1 -1
- data/lib/mongoid/factory.rb +8 -6
- data/lib/mongoid/fields.rb +41 -8
- data/lib/mongoid/fields/foreign_key.rb +3 -3
- data/lib/mongoid/fields/localized.rb +1 -1
- data/lib/mongoid/fields/standard.rb +5 -17
- data/lib/mongoid/fields/validators/macro.rb +15 -5
- data/lib/mongoid/{finders.rb → findable.rb} +35 -7
- data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
- data/lib/mongoid/indexable/specification.rb +104 -0
- data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
- data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
- data/lib/mongoid/{callbacks.rb → interceptable.rb} +30 -62
- data/lib/mongoid/log_subscriber.rb +55 -0
- data/lib/mongoid/matchable.rb +152 -0
- data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/ne.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
- data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
- data/lib/mongoid/persistable.rb +216 -0
- data/lib/mongoid/persistable/creatable.rb +189 -0
- data/lib/mongoid/persistable/deletable.rb +149 -0
- data/lib/mongoid/persistable/destroyable.rb +60 -0
- data/lib/mongoid/persistable/incrementable.rb +36 -0
- data/lib/mongoid/persistable/logical.rb +38 -0
- data/lib/mongoid/persistable/poppable.rb +39 -0
- data/lib/mongoid/persistable/pullable.rb +55 -0
- data/lib/mongoid/persistable/pushable.rb +62 -0
- data/lib/mongoid/persistable/renamable.rb +35 -0
- data/lib/mongoid/persistable/savable.rb +52 -0
- data/lib/mongoid/persistable/settable.rb +33 -0
- data/lib/mongoid/persistable/unsettable.rb +36 -0
- data/lib/mongoid/persistable/updatable.rb +153 -0
- data/lib/mongoid/persistable/upsertable.rb +55 -0
- data/lib/mongoid/positional.rb +71 -0
- data/lib/mongoid/query_cache.rb +255 -0
- data/lib/mongoid/railtie.rb +34 -60
- data/lib/mongoid/railties/database.rake +9 -25
- data/lib/mongoid/relations.rb +11 -25
- data/lib/mongoid/relations/accessors.rb +15 -51
- data/lib/mongoid/relations/auto_save.rb +15 -36
- data/lib/mongoid/relations/binding.rb +2 -25
- data/lib/mongoid/relations/bindings/embedded/in.rb +1 -1
- data/lib/mongoid/relations/bindings/embedded/many.rb +1 -3
- data/lib/mongoid/relations/bindings/referenced/in.rb +3 -8
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -2
- data/lib/mongoid/relations/builder.rb +1 -1
- data/lib/mongoid/relations/builders.rb +2 -2
- data/lib/mongoid/relations/builders/embedded/one.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +5 -6
- data/lib/mongoid/relations/builders/referenced/in.rb +1 -1
- data/lib/mongoid/relations/builders/referenced/many.rb +1 -2
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +1 -2
- data/lib/mongoid/relations/builders/referenced/one.rb +1 -1
- data/lib/mongoid/relations/cascading.rb +3 -5
- data/lib/mongoid/relations/constraint.rb +1 -1
- data/lib/mongoid/relations/conversions.rb +1 -1
- data/lib/mongoid/relations/counter_cache.rb +39 -15
- data/lib/mongoid/relations/eager.rb +46 -0
- data/lib/mongoid/relations/eager/base.rb +149 -0
- data/lib/mongoid/relations/eager/belongs_to.rb +31 -0
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +47 -0
- data/lib/mongoid/relations/eager/has_many.rb +38 -0
- data/lib/mongoid/relations/eager/has_one.rb +30 -0
- data/lib/mongoid/relations/embedded/batchable.rb +4 -5
- data/lib/mongoid/relations/embedded/in.rb +4 -4
- data/lib/mongoid/relations/embedded/many.rb +14 -32
- data/lib/mongoid/relations/embedded/one.rb +1 -1
- data/lib/mongoid/relations/macros.rb +3 -4
- data/lib/mongoid/relations/many.rb +51 -31
- data/lib/mongoid/relations/marshalable.rb +3 -3
- data/lib/mongoid/relations/metadata.rb +14 -79
- data/lib/mongoid/relations/nested_builder.rb +2 -2
- data/lib/mongoid/relations/one.rb +1 -1
- data/lib/mongoid/relations/options.rb +1 -0
- data/lib/mongoid/relations/polymorphic.rb +0 -1
- data/lib/mongoid/relations/proxy.rb +21 -41
- data/lib/mongoid/relations/referenced/in.rb +4 -20
- data/lib/mongoid/relations/referenced/many.rb +22 -35
- data/lib/mongoid/relations/referenced/many_to_many.rb +19 -42
- data/lib/mongoid/relations/referenced/one.rb +6 -25
- data/lib/mongoid/relations/synchronization.rb +4 -4
- data/lib/mongoid/relations/targets/enumerable.rb +10 -10
- data/lib/mongoid/relations/touchable.rb +34 -1
- data/lib/mongoid/{reloading.rb → reloadable.rb} +7 -5
- data/lib/mongoid/{scoping.rb → scopable.rb} +36 -36
- data/lib/mongoid/selectable.rb +59 -0
- data/lib/mongoid/{serialization.rb → serializable.rb} +11 -2
- data/lib/mongoid/sessions.rb +37 -345
- data/lib/mongoid/sessions/factory.rb +2 -0
- data/lib/mongoid/sessions/options.rb +185 -0
- data/lib/mongoid/sessions/storage_options.rb +140 -0
- data/lib/mongoid/sessions/thread_options.rb +19 -0
- data/lib/mongoid/sessions/validators/storage.rb +16 -3
- data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
- data/lib/mongoid/{state.rb → stateful.rb} +13 -1
- data/lib/mongoid/support/query_counter.rb +23 -0
- data/lib/mongoid/tasks/database.rake +31 -0
- data/lib/mongoid/tasks/database.rb +107 -0
- data/lib/mongoid/threaded.rb +26 -172
- data/lib/mongoid/threaded/lifecycle.rb +0 -28
- data/lib/mongoid/timestamps/updated/short.rb +2 -2
- data/lib/mongoid/{hierarchy.rb → traversable.rb} +15 -7
- data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
- data/lib/mongoid/{validations → validatable}/associated.rb +4 -2
- data/lib/mongoid/{validations → validatable}/format.rb +1 -1
- data/lib/mongoid/{validations → validatable}/length.rb +1 -1
- data/lib/mongoid/{validations → validatable}/localizable.rb +1 -1
- data/lib/mongoid/{validations → validatable}/macros.rb +4 -3
- data/lib/mongoid/{validations → validatable}/presence.rb +1 -1
- data/lib/mongoid/{validations → validatable}/queryable.rb +1 -2
- data/lib/mongoid/{validations → validatable}/uniqueness.rb +25 -21
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +46 -25
- data/lib/rails/generators/mongoid/model/model_generator.rb +0 -1
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +0 -3
- data/lib/rails/generators/mongoid_generator.rb +3 -40
- data/lib/rails/mongoid.rb +0 -122
- data/lib/support/ruby_version.rb +1 -1
- data/spec/app/models/account.rb +2 -6
- data/spec/app/models/acolyte.rb +2 -1
- data/spec/app/models/actor.rb +0 -1
- data/spec/app/models/address.rb +8 -3
- data/spec/app/models/animal.rb +1 -1
- data/spec/app/models/appointment.rb +3 -3
- data/spec/app/models/article.rb +1 -4
- data/spec/app/models/audio.rb +5 -0
- data/spec/app/models/author.rb +0 -2
- data/spec/app/models/band.rb +3 -2
- data/spec/app/models/bar.rb +1 -0
- data/spec/app/models/book.rb +1 -0
- data/spec/app/models/building.rb +0 -2
- data/spec/app/models/building_address.rb +0 -2
- data/spec/app/models/bus.rb +1 -1
- data/spec/app/models/canvas.rb +1 -1
- data/spec/app/models/contextable_item.rb +5 -0
- data/spec/app/models/contractor.rb +0 -2
- data/spec/app/models/country_code.rb +1 -1
- data/spec/app/models/definition.rb +2 -2
- data/spec/app/models/dog.rb +1 -1
- data/spec/app/models/draft.rb +9 -0
- data/spec/app/models/dragon.rb +4 -0
- data/spec/app/models/drug.rb +1 -3
- data/spec/app/models/dungeon.rb +4 -0
- data/spec/app/models/edit.rb +5 -0
- data/spec/app/models/even.rb +7 -0
- data/spec/app/models/event.rb +1 -1
- data/spec/app/models/filesystem.rb +1 -0
- data/spec/app/models/fish.rb +0 -1
- data/spec/app/models/fruits.rb +6 -0
- data/spec/app/models/game.rb +0 -2
- data/spec/app/models/house.rb +1 -3
- data/spec/app/models/id_key.rb +6 -0
- data/spec/app/models/item.rb +1 -5
- data/spec/app/models/jar.rb +1 -1
- data/spec/app/models/label.rb +4 -4
- data/spec/app/models/line_item.rb +1 -1
- data/spec/app/models/login.rb +1 -1
- data/spec/app/models/message.rb +8 -0
- data/spec/app/models/movie.rb +1 -0
- data/spec/app/models/name.rb +3 -3
- data/spec/app/models/note.rb +3 -1
- data/spec/app/models/odd.rb +7 -0
- data/spec/app/models/oscar.rb +1 -1
- data/spec/app/models/parent_doc.rb +1 -1
- data/spec/app/models/person.rb +16 -10
- data/spec/app/models/phone.rb +1 -3
- data/spec/app/models/player.rb +3 -3
- data/spec/app/models/post.rb +5 -3
- data/spec/app/models/preference.rb +1 -1
- data/spec/app/models/quiz.rb +0 -3
- data/spec/app/models/record.rb +10 -5
- data/spec/app/models/registry.rb +1 -1
- data/spec/app/models/server.rb +1 -1
- data/spec/app/models/service.rb +3 -3
- data/spec/app/models/sound.rb +5 -0
- data/spec/app/models/symptom.rb +1 -1
- data/spec/app/models/template.rb +1 -1
- data/spec/app/models/title.rb +0 -1
- data/spec/app/models/track.rb +5 -5
- data/spec/app/models/tree.rb +3 -3
- data/spec/app/models/video.rb +1 -5
- data/spec/app/models/wiki_page.rb +2 -5
- data/spec/app/models/word.rb +3 -0
- data/spec/app/models/word_origin.rb +1 -1
- data/spec/config/mongoid.yml +7 -8
- data/spec/helpers.rb +18 -0
- data/spec/mongoid/#atomic_spec.rb# +365 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +22 -22
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +8 -49
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +7 -49
- data/spec/mongoid/atomic/paths/root_spec.rb +3 -61
- data/spec/mongoid/atomic/paths_spec.rb +19 -19
- data/spec/mongoid/atomic_spec.rb +19 -19
- data/spec/mongoid/{nested_attributes_spec.rb → attributes/nested_spec.rb} +474 -592
- data/spec/mongoid/attributes/readonly_spec.rb +58 -18
- data/spec/mongoid/attributes_spec.rb +349 -434
- data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +203 -153
- data/spec/mongoid/{components_spec.rb → composable_spec.rb} +3 -3
- data/spec/mongoid/config/environment_spec.rb +3 -3
- data/spec/mongoid/config/options_spec.rb +6 -6
- data/spec/mongoid/config_spec.rb +24 -48
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +12 -12
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +78 -38
- data/spec/mongoid/contextual/atomic_spec.rb +60 -56
- data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
- data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
- data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
- data/spec/mongoid/contextual/memory_spec.rb +156 -94
- data/spec/mongoid/contextual/mongo_spec.rb +238 -150
- data/spec/mongoid/contextual/none_spec.rb +127 -0
- data/spec/mongoid/contextual/text_search_spec.rb +209 -0
- data/spec/mongoid/copyable_spec.rb +56 -68
- data/spec/mongoid/criteria/findable_spec.rb +991 -0
- data/spec/mongoid/{criterion/inspection_spec.rb → criteria/inspectable_spec.rb} +5 -5
- data/spec/mongoid/{criterion → criteria}/marshalable_spec.rb +2 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +1252 -0
- data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
- data/spec/mongoid/criteria_spec.rb +715 -2421
- data/spec/mongoid/document_spec.rb +171 -121
- data/spec/mongoid/equality_spec.rb +22 -22
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +3 -3
- data/spec/mongoid/errors/callback_spec.rb +3 -3
- data/spec/mongoid/errors/delete_restriction_spec.rb +3 -3
- data/spec/mongoid/errors/document_not_destroyed_spec.rb +33 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +11 -11
- data/spec/mongoid/errors/eager_load_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_collection_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_config_option_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_field_option_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_field_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_find_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_includes_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_index_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_options_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_path_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_scope_spec.rb +5 -5
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +3 -3
- data/spec/mongoid/errors/invalid_time_spec.rb +3 -3
- data/spec/mongoid/errors/inverse_not_found_spec.rb +3 -3
- data/spec/mongoid/errors/mixed_relations_spec.rb +3 -3
- data/spec/mongoid/errors/mixed_session_configuration_spec.rb +3 -3
- data/spec/mongoid/errors/mongoid_error_spec.rb +8 -8
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +3 -3
- data/spec/mongoid/errors/no_environment_spec.rb +3 -3
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +3 -3
- data/spec/mongoid/errors/no_metadata_spec.rb +3 -3
- data/spec/mongoid/errors/no_parent_spec.rb +3 -3
- data/spec/mongoid/errors/no_session_config_spec.rb +3 -3
- data/spec/mongoid/errors/no_session_database_spec.rb +3 -3
- data/spec/mongoid/errors/no_session_hosts_spec.rb +3 -3
- data/spec/mongoid/errors/no_sessions_config_spec.rb +3 -3
- data/spec/mongoid/errors/readonly_attribute_spec.rb +3 -3
- data/spec/mongoid/errors/readonly_document_spec.rb +29 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +3 -3
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +3 -3
- data/spec/mongoid/errors/unknown_attribute_spec.rb +5 -5
- data/spec/mongoid/errors/unsaved_document_spec.rb +3 -3
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +3 -3
- data/spec/mongoid/errors/validations_spec.rb +7 -7
- data/spec/mongoid/extensions/array_spec.rb +61 -61
- data/spec/mongoid/extensions/big_decimal_spec.rb +11 -11
- data/spec/mongoid/extensions/binary_spec.rb +12 -12
- data/spec/mongoid/extensions/boolean_spec.rb +18 -18
- data/spec/mongoid/extensions/date_spec.rb +13 -13
- data/spec/mongoid/extensions/date_time_spec.rb +8 -8
- data/spec/mongoid/extensions/false_class_spec.rb +5 -5
- data/spec/mongoid/extensions/float_spec.rb +29 -15
- data/spec/mongoid/extensions/hash_spec.rb +29 -29
- data/spec/mongoid/extensions/integer_spec.rb +15 -15
- data/spec/mongoid/extensions/module_spec.rb +2 -2
- data/spec/mongoid/extensions/nil_class_spec.rb +1 -1
- data/spec/mongoid/extensions/object_id_spec.rb +134 -134
- data/spec/mongoid/extensions/object_spec.rb +26 -26
- data/spec/mongoid/extensions/range_spec.rb +61 -12
- data/spec/mongoid/extensions/regexp_spec.rb +4 -4
- data/spec/mongoid/extensions/set_spec.rb +4 -4
- data/spec/mongoid/extensions/string_spec.rb +35 -46
- data/spec/mongoid/extensions/symbol_spec.rb +9 -9
- data/spec/mongoid/extensions/time_spec.rb +49 -49
- data/spec/mongoid/extensions/time_with_zone_spec.rb +34 -34
- data/spec/mongoid/extensions/true_class_spec.rb +5 -5
- data/spec/mongoid/extensions_spec.rb +29 -0
- data/spec/mongoid/factory_spec.rb +15 -15
- data/spec/mongoid/fields/foreign_key_spec.rb +73 -66
- data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +15 -15
- data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +22 -22
- data/spec/mongoid/fields/localized_spec.rb +38 -23
- data/spec/mongoid/fields/standard_spec.rb +12 -12
- data/spec/mongoid/fields_spec.rb +263 -217
- data/spec/mongoid/findable_spec.rb +509 -0
- data/spec/mongoid/indexable/specification_spec.rb +102 -0
- data/spec/mongoid/{indexes_spec.rb → indexable_spec.rb} +171 -51
- data/spec/mongoid/{inspection_spec.rb → inspectable_spec.rb} +6 -14
- data/spec/mongoid/{callbacks_spec.rb → interceptable_spec.rb} +117 -116
- data/spec/mongoid/log_subscriber_spec.rb +75 -0
- data/spec/mongoid/loggable_spec.rb +1 -1
- data/spec/mongoid/{matchers → matchable}/all_spec.rb +4 -4
- data/spec/mongoid/{matchers → matchable}/and_spec.rb +11 -11
- data/spec/mongoid/{matchers → matchable}/default_spec.rb +15 -15
- data/spec/mongoid/{matchers → matchable}/exists_spec.rb +5 -5
- data/spec/mongoid/{matchers → matchable}/gt_spec.rb +9 -8
- data/spec/mongoid/{matchers → matchable}/gte_spec.rb +7 -7
- data/spec/mongoid/matchable/in_spec.rb +49 -0
- data/spec/mongoid/{matchers → matchable}/lt_spec.rb +7 -7
- data/spec/mongoid/{matchers → matchable}/lte_spec.rb +7 -7
- data/spec/mongoid/matchable/ne_spec.rb +46 -0
- data/spec/mongoid/matchable/nin_spec.rb +48 -0
- data/spec/mongoid/{matchers → matchable}/or_spec.rb +6 -6
- data/spec/mongoid/{matchers → matchable}/size_spec.rb +3 -3
- data/spec/mongoid/{matchers_spec.rb → matchable_spec.rb} +41 -41
- data/spec/mongoid/persistable/creatable_spec.rb +553 -0
- data/spec/mongoid/persistable/deletable_spec.rb +218 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +192 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
- data/spec/mongoid/persistable/logical_spec.rb +143 -0
- data/spec/mongoid/persistable/poppable_spec.rb +115 -0
- data/spec/mongoid/persistable/pullable_spec.rb +228 -0
- data/spec/mongoid/persistable/pushable_spec.rb +258 -0
- data/spec/mongoid/persistable/renamable_spec.rb +135 -0
- data/spec/mongoid/persistable/savable_spec.rb +498 -0
- data/spec/mongoid/persistable/settable_spec.rb +162 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
- data/spec/mongoid/persistable/updatable_spec.rb +558 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
- data/spec/mongoid/persistable_spec.rb +206 -0
- data/spec/mongoid/{atomic/positionable_spec.rb → positional_spec.rb} +14 -19
- data/spec/mongoid/query_cache_spec.rb +263 -0
- data/spec/mongoid/railties/document_spec.rb +2 -2
- data/spec/mongoid/relations/accessors_spec.rb +53 -145
- data/spec/mongoid/relations/auto_save_spec.rb +37 -17
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +12 -12
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +3 -3
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +5 -5
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +26 -26
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +10 -10
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +19 -19
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +12 -12
- data/spec/mongoid/relations/builders/embedded/in_spec.rb +4 -4
- data/spec/mongoid/relations/builders/embedded/many_spec.rb +18 -18
- data/spec/mongoid/relations/builders/embedded/one_spec.rb +11 -11
- data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +12 -13
- data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +14 -14
- data/spec/mongoid/relations/builders/referenced/in_spec.rb +24 -35
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +15 -15
- data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +18 -18
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +12 -25
- data/spec/mongoid/relations/builders_spec.rb +21 -21
- data/spec/mongoid/relations/cascading/delete_spec.rb +9 -9
- data/spec/mongoid/relations/cascading/destroy_spec.rb +6 -6
- data/spec/mongoid/relations/cascading/nullify_spec.rb +4 -4
- data/spec/mongoid/relations/cascading/restrict_spec.rb +7 -7
- data/spec/mongoid/relations/cascading_spec.rb +16 -16
- data/spec/mongoid/relations/constraint_spec.rb +8 -7
- data/spec/mongoid/relations/conversions_spec.rb +16 -14
- data/spec/mongoid/relations/counter_cache_spec.rb +85 -0
- data/spec/mongoid/relations/cyclic_spec.rb +18 -18
- data/spec/mongoid/relations/eager/belongs_to_spec.rb +154 -0
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +117 -0
- data/spec/mongoid/relations/eager/has_many_spec.rb +207 -0
- data/spec/mongoid/relations/eager/has_one_spec.rb +163 -0
- data/spec/mongoid/relations/eager_spec.rb +228 -0
- data/spec/mongoid/relations/embedded/dirty_spec.rb +8 -8
- data/spec/mongoid/relations/embedded/in_spec.rb +56 -57
- data/spec/mongoid/relations/embedded/many_spec.rb +467 -372
- data/spec/mongoid/relations/embedded/one_spec.rb +108 -141
- data/spec/mongoid/relations/macros_spec.rb +108 -102
- data/spec/mongoid/relations/metadata_spec.rb +180 -255
- data/spec/mongoid/relations/options_spec.rb +1 -1
- data/spec/mongoid/relations/polymorphic_spec.rb +13 -17
- data/spec/mongoid/relations/proxy_spec.rb +2 -2
- data/spec/mongoid/relations/referenced/in_spec.rb +128 -303
- data/spec/mongoid/relations/referenced/many_spec.rb +587 -527
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +401 -424
- data/spec/mongoid/relations/referenced/one_spec.rb +149 -264
- data/spec/mongoid/relations/reflections_spec.rb +6 -6
- data/spec/mongoid/relations/synchronization_spec.rb +46 -50
- data/spec/mongoid/relations/targets/enumerable_spec.rb +118 -118
- data/spec/mongoid/relations/touchable_spec.rb +333 -0
- data/spec/mongoid/relations_spec.rb +16 -15
- data/spec/mongoid/{reloading_spec.rb → reloadable_spec.rb} +38 -55
- data/spec/mongoid/{scoping_spec.rb → scopable_spec.rb} +89 -164
- data/spec/mongoid/selectable_spec.rb +134 -0
- data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +129 -82
- data/spec/mongoid/sessions/factory_spec.rb +49 -28
- data/spec/mongoid/sessions/mongo_uri_spec.rb +7 -7
- data/spec/mongoid/sessions/options_spec.rb +108 -0
- data/spec/mongoid/sessions_spec.rb +319 -178
- data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
- data/spec/mongoid/{state_spec.rb → stateful_spec.rb} +36 -11
- data/spec/mongoid/tasks/database_rake_spec.rb +285 -0
- data/spec/mongoid/tasks/database_spec.rb +160 -0
- data/spec/mongoid/threaded_spec.rb +17 -70
- data/spec/mongoid/timestamps/created/short_spec.rb +6 -6
- data/spec/mongoid/timestamps/created_spec.rb +5 -5
- data/spec/mongoid/timestamps/timeless_spec.rb +6 -6
- data/spec/mongoid/timestamps/updated/short_spec.rb +11 -11
- data/spec/mongoid/timestamps/updated_spec.rb +9 -13
- data/spec/mongoid/timestamps_spec.rb +9 -13
- data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
- data/spec/mongoid/{validations → validatable}/associated_spec.rb +45 -22
- data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
- data/spec/mongoid/{validations → validatable}/length_spec.rb +14 -14
- data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
- data/spec/mongoid/{validations → validatable}/presence_spec.rb +37 -44
- data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +184 -192
- data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
- data/spec/mongoid_spec.rb +8 -8
- data/spec/rails/mongoid_spec.rb +19 -335
- data/spec/spec_helper.rb +31 -13
- metadata +303 -283
- data/lib/mongoid/atomic/positionable.rb +0 -73
- data/lib/mongoid/components.rb +0 -92
- data/lib/mongoid/config/inflections.rb +0 -6
- data/lib/mongoid/contextual/eager.rb +0 -158
- data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
- data/lib/mongoid/identity_map.rb +0 -163
- data/lib/mongoid/json.rb +0 -16
- data/lib/mongoid/matchers.rb +0 -32
- data/lib/mongoid/matchers/strategies.rb +0 -97
- data/lib/mongoid/multi_parameter_attributes.rb +0 -105
- data/lib/mongoid/nested_attributes.rb +0 -78
- data/lib/mongoid/observer.rb +0 -192
- data/lib/mongoid/paranoia.rb +0 -136
- data/lib/mongoid/persistence.rb +0 -357
- data/lib/mongoid/persistence/atomic.rb +0 -231
- data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
- data/lib/mongoid/persistence/atomic/bit.rb +0 -35
- data/lib/mongoid/persistence/atomic/inc.rb +0 -45
- data/lib/mongoid/persistence/atomic/operation.rb +0 -154
- data/lib/mongoid/persistence/atomic/pop.rb +0 -32
- data/lib/mongoid/persistence/atomic/pull.rb +0 -32
- data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
- data/lib/mongoid/persistence/atomic/push.rb +0 -25
- data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
- data/lib/mongoid/persistence/atomic/rename.rb +0 -30
- data/lib/mongoid/persistence/atomic/sets.rb +0 -28
- data/lib/mongoid/persistence/atomic/unset.rb +0 -27
- data/lib/mongoid/persistence/deletion.rb +0 -31
- data/lib/mongoid/persistence/insertion.rb +0 -38
- data/lib/mongoid/persistence/modification.rb +0 -35
- data/lib/mongoid/persistence/operations.rb +0 -214
- data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
- data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
- data/lib/mongoid/persistence/operations/insert.rb +0 -34
- data/lib/mongoid/persistence/operations/remove.rb +0 -33
- data/lib/mongoid/persistence/operations/update.rb +0 -59
- data/lib/mongoid/persistence/operations/upsert.rb +0 -28
- data/lib/mongoid/persistence/upsertion.rb +0 -31
- data/lib/mongoid/unit_of_work.rb +0 -61
- data/lib/mongoid/versioning.rb +0 -217
- data/lib/rack/mongoid.rb +0 -2
- data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
- data/spec/app/models/actor_observer.rb +0 -15
- data/spec/app/models/callback_recorder.rb +0 -25
- data/spec/app/models/paranoid_phone.rb +0 -25
- data/spec/app/models/paranoid_post.rb +0 -36
- data/spec/app/models/phone_observer.rb +0 -6
- data/spec/mongoid/attributes/processing_spec.rb +0 -149
- data/spec/mongoid/criterion/destructive_spec.rb +0 -101
- data/spec/mongoid/criterion/modifiable_spec.rb +0 -409
- data/spec/mongoid/criterion/modification_spec.rb +0 -402
- data/spec/mongoid/errors/versioning_not_on_root_spec.rb +0 -29
- data/spec/mongoid/finders_spec.rb +0 -321
- data/spec/mongoid/identity_map_spec.rb +0 -564
- data/spec/mongoid/json_spec.rb +0 -33
- data/spec/mongoid/matchers/in_spec.rb +0 -25
- data/spec/mongoid/matchers/ne_spec.rb +0 -25
- data/spec/mongoid/matchers/nin_spec.rb +0 -25
- data/spec/mongoid/multi_parameter_attributes_spec.rb +0 -128
- data/spec/mongoid/observer_spec.rb +0 -290
- data/spec/mongoid/paranoia_spec.rb +0 -759
- data/spec/mongoid/persistence/atomic/add_to_set_spec.rb +0 -262
- data/spec/mongoid/persistence/atomic/bit_spec.rb +0 -88
- data/spec/mongoid/persistence/atomic/inc_spec.rb +0 -133
- data/spec/mongoid/persistence/atomic/pop_spec.rb +0 -111
- data/spec/mongoid/persistence/atomic/pull_all_spec.rb +0 -77
- data/spec/mongoid/persistence/atomic/pull_spec.rb +0 -80
- data/spec/mongoid/persistence/atomic/push_all_spec.rb +0 -77
- data/spec/mongoid/persistence/atomic/push_spec.rb +0 -77
- data/spec/mongoid/persistence/atomic/rename_spec.rb +0 -42
- data/spec/mongoid/persistence/atomic/sets_spec.rb +0 -154
- data/spec/mongoid/persistence/atomic/unset_spec.rb +0 -65
- data/spec/mongoid/persistence/atomic_spec.rb +0 -216
- data/spec/mongoid/persistence/operations/embedded/insert_spec.rb +0 -191
- data/spec/mongoid/persistence/operations/embedded/remove_spec.rb +0 -8
- data/spec/mongoid/persistence/operations/insert_spec.rb +0 -149
- data/spec/mongoid/persistence/operations/remove_spec.rb +0 -113
- data/spec/mongoid/persistence/operations/update_spec.rb +0 -141
- data/spec/mongoid/persistence/operations/upsert_spec.rb +0 -59
- data/spec/mongoid/persistence/operations_spec.rb +0 -313
- data/spec/mongoid/persistence_spec.rb +0 -2279
- data/spec/mongoid/unit_of_work_spec.rb +0 -196
- data/spec/mongoid/versioning_spec.rb +0 -540
- data/spec/rack/mongoid/middleware/identity_map_spec.rb +0 -72
@@ -1,313 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mongoid::Persistence::Operations do
|
4
|
-
|
5
|
-
let(:document) do
|
6
|
-
Person.new
|
7
|
-
end
|
8
|
-
|
9
|
-
let(:klass) do
|
10
|
-
Class.new do
|
11
|
-
include Mongoid::Persistence::Operations
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "#collection" do
|
16
|
-
|
17
|
-
let(:options) do
|
18
|
-
{ validate: true }
|
19
|
-
end
|
20
|
-
|
21
|
-
context "when the document is a root" do
|
22
|
-
|
23
|
-
let(:operation) do
|
24
|
-
klass.new(document, options)
|
25
|
-
end
|
26
|
-
|
27
|
-
let(:collection) do
|
28
|
-
operation.collection
|
29
|
-
end
|
30
|
-
|
31
|
-
it "returns the root collection" do
|
32
|
-
collection.name.should eq(document.collection.name)
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context "when the document is embedded" do
|
37
|
-
|
38
|
-
let(:name) do
|
39
|
-
document.build_name(first_name: "Syd")
|
40
|
-
end
|
41
|
-
|
42
|
-
let(:operation) do
|
43
|
-
klass.new(name, options)
|
44
|
-
end
|
45
|
-
|
46
|
-
let(:collection) do
|
47
|
-
operation.collection
|
48
|
-
end
|
49
|
-
|
50
|
-
it "returns the root collection" do
|
51
|
-
collection.name.should eq(document.collection.name)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
describe "#deletes" do
|
57
|
-
|
58
|
-
context "when the child is an embeds one" do
|
59
|
-
|
60
|
-
let(:child) do
|
61
|
-
document.build_name(first_name: "Syd")
|
62
|
-
end
|
63
|
-
|
64
|
-
let(:operation) do
|
65
|
-
klass.new(child)
|
66
|
-
end
|
67
|
-
|
68
|
-
let(:deletes) do
|
69
|
-
operation.deletes
|
70
|
-
end
|
71
|
-
|
72
|
-
it "returns the delete atomic modifiers" do
|
73
|
-
deletes.should eq(
|
74
|
-
{ "$unset" => { "name" => true } }
|
75
|
-
)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
context "when the child is an embeds many" do
|
80
|
-
|
81
|
-
let(:child) do
|
82
|
-
document.addresses.build(street: "Unter den Linden")
|
83
|
-
end
|
84
|
-
|
85
|
-
let(:operation) do
|
86
|
-
klass.new(child)
|
87
|
-
end
|
88
|
-
|
89
|
-
let(:deletes) do
|
90
|
-
operation.deletes
|
91
|
-
end
|
92
|
-
|
93
|
-
it "returns the delete atomic modifiers" do
|
94
|
-
deletes.should eq(
|
95
|
-
{ "$pull" => { "addresses" => { "_id" => "unter-den-linden" } } }
|
96
|
-
)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
describe "#inserts" do
|
102
|
-
|
103
|
-
let(:child) do
|
104
|
-
document.build_name(first_name: "Syd")
|
105
|
-
end
|
106
|
-
|
107
|
-
let(:operation) do
|
108
|
-
klass.new(child)
|
109
|
-
end
|
110
|
-
|
111
|
-
let(:inserts) do
|
112
|
-
operation.inserts
|
113
|
-
end
|
114
|
-
|
115
|
-
it "returns the insert atomic modifiers" do
|
116
|
-
inserts.should eq(
|
117
|
-
{ "$set" => { "name" => { "first_name" => "Syd", "_id" => "Syd-" } } }
|
118
|
-
)
|
119
|
-
end
|
120
|
-
end
|
121
|
-
|
122
|
-
describe "#notifying_parent?" do
|
123
|
-
|
124
|
-
let(:operation) do
|
125
|
-
klass.new(document, options)
|
126
|
-
end
|
127
|
-
|
128
|
-
context "when the suppress option is true" do
|
129
|
-
|
130
|
-
let(:options) do
|
131
|
-
{ suppress: true }
|
132
|
-
end
|
133
|
-
|
134
|
-
it "returns false" do
|
135
|
-
operation.should_not be_notifying_parent
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
context "when the suppress option is false" do
|
140
|
-
|
141
|
-
let(:options) do
|
142
|
-
{ suppress: false }
|
143
|
-
end
|
144
|
-
|
145
|
-
it "returns true" do
|
146
|
-
operation.should be_notifying_parent
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
context "when the suppress option is nil" do
|
151
|
-
|
152
|
-
let(:options) do
|
153
|
-
{}
|
154
|
-
end
|
155
|
-
|
156
|
-
it "returns true" do
|
157
|
-
operation.should be_notifying_parent
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
describe "#options" do
|
163
|
-
|
164
|
-
let(:options) do
|
165
|
-
{}
|
166
|
-
end
|
167
|
-
|
168
|
-
let(:operation) do
|
169
|
-
klass.new(document, options)
|
170
|
-
end
|
171
|
-
|
172
|
-
it "returns the options" do
|
173
|
-
operation.options.should eq(options)
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
describe "#parent" do
|
178
|
-
|
179
|
-
let(:child) do
|
180
|
-
document.addresses.build(street: "Unter den Linden")
|
181
|
-
end
|
182
|
-
|
183
|
-
let(:operation) do
|
184
|
-
klass.new(child)
|
185
|
-
end
|
186
|
-
|
187
|
-
it "returns the document's parent" do
|
188
|
-
operation.parent.should eq(document)
|
189
|
-
end
|
190
|
-
end
|
191
|
-
|
192
|
-
describe "#selector" do
|
193
|
-
|
194
|
-
let(:operation) do
|
195
|
-
klass.new(document)
|
196
|
-
end
|
197
|
-
|
198
|
-
it "returns the document's atomic selector" do
|
199
|
-
operation.selector.should eq(document.atomic_selector)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
describe "#updates" do
|
204
|
-
|
205
|
-
context "when there are no conflicting mods" do
|
206
|
-
|
207
|
-
let(:operation) do
|
208
|
-
klass.new(document)
|
209
|
-
end
|
210
|
-
|
211
|
-
let(:updates) do
|
212
|
-
operation.updates
|
213
|
-
end
|
214
|
-
|
215
|
-
it "returns the updates" do
|
216
|
-
updates.should eq(document.atomic_updates)
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
context "when conflicting mods exist" do
|
221
|
-
|
222
|
-
let!(:document) do
|
223
|
-
Person.new.tap do |person|
|
224
|
-
person.new_record = false
|
225
|
-
person.move_changes
|
226
|
-
end
|
227
|
-
end
|
228
|
-
|
229
|
-
let!(:child) do
|
230
|
-
document.addresses.build(street: "Unter den Linden").tap do |doc|
|
231
|
-
doc.new_record = false
|
232
|
-
end
|
233
|
-
end
|
234
|
-
|
235
|
-
let!(:conflict) do
|
236
|
-
document.addresses.build(street: "Freiderichstr")
|
237
|
-
end
|
238
|
-
|
239
|
-
let(:operation) do
|
240
|
-
klass.new(document)
|
241
|
-
end
|
242
|
-
|
243
|
-
let!(:updates) do
|
244
|
-
operation.updates
|
245
|
-
end
|
246
|
-
|
247
|
-
let!(:conflicts) do
|
248
|
-
operation.conflicts
|
249
|
-
end
|
250
|
-
|
251
|
-
it "returns the updates without conflicts" do
|
252
|
-
updates.should eq(
|
253
|
-
{
|
254
|
-
"$set" => {
|
255
|
-
"addresses.0.street" => "Unter den Linden",
|
256
|
-
"addresses.0._id" => "unter-den-linden"
|
257
|
-
}
|
258
|
-
}
|
259
|
-
)
|
260
|
-
end
|
261
|
-
|
262
|
-
it "sets the conflicts" do
|
263
|
-
conflicts.should eq(
|
264
|
-
{
|
265
|
-
"$pushAll" => {
|
266
|
-
"addresses" => [ { "street" => "Freiderichstr", "_id" => "freiderichstr" } ]
|
267
|
-
}
|
268
|
-
}
|
269
|
-
)
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
describe "#validating?" do
|
275
|
-
|
276
|
-
let(:operation) do
|
277
|
-
klass.new(document, options)
|
278
|
-
end
|
279
|
-
|
280
|
-
context "when validate option is true" do
|
281
|
-
|
282
|
-
let(:options) do
|
283
|
-
{ validate: true }
|
284
|
-
end
|
285
|
-
|
286
|
-
it "returns true" do
|
287
|
-
operation.should be_validating
|
288
|
-
end
|
289
|
-
end
|
290
|
-
|
291
|
-
context "when validate option is false" do
|
292
|
-
|
293
|
-
let(:options) do
|
294
|
-
{ validate: false }
|
295
|
-
end
|
296
|
-
|
297
|
-
it "returns false" do
|
298
|
-
operation.should_not be_validating
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
context "when validate option is nil" do
|
303
|
-
|
304
|
-
let(:options) do
|
305
|
-
{}
|
306
|
-
end
|
307
|
-
|
308
|
-
it "returns true" do
|
309
|
-
operation.should be_validating
|
310
|
-
end
|
311
|
-
end
|
312
|
-
end
|
313
|
-
end
|
@@ -1,2279 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mongoid::Persistence do
|
4
|
-
|
5
|
-
describe ".create" do
|
6
|
-
|
7
|
-
context "when provided an array of attributes" do
|
8
|
-
|
9
|
-
context "when no block is passed" do
|
10
|
-
|
11
|
-
let(:people) do
|
12
|
-
Person.create([{ title: "sir" }, { title: "madam" }])
|
13
|
-
end
|
14
|
-
|
15
|
-
it "creates the first document" do
|
16
|
-
people.first.title.should eq("sir")
|
17
|
-
end
|
18
|
-
|
19
|
-
it "persists the first document" do
|
20
|
-
people.first.should be_persisted
|
21
|
-
end
|
22
|
-
|
23
|
-
it "creates the second document" do
|
24
|
-
people.last.title.should eq("madam")
|
25
|
-
end
|
26
|
-
|
27
|
-
it "persists the second document" do
|
28
|
-
people.last.should be_persisted
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
context "when no block is passed" do
|
33
|
-
|
34
|
-
let(:people) do
|
35
|
-
Person.create([{ title: "sir" }, { title: "madam" }]) do |person|
|
36
|
-
person.age = 36
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
it "creates the first document" do
|
41
|
-
people.first.title.should eq("sir")
|
42
|
-
end
|
43
|
-
|
44
|
-
it "persists the first document" do
|
45
|
-
people.first.should be_persisted
|
46
|
-
end
|
47
|
-
|
48
|
-
it "passes the block to the first document" do
|
49
|
-
people.first.age.should eq(36)
|
50
|
-
end
|
51
|
-
|
52
|
-
it "creates the second document" do
|
53
|
-
people.last.title.should eq("madam")
|
54
|
-
end
|
55
|
-
|
56
|
-
it "persists the second document" do
|
57
|
-
people.last.should be_persisted
|
58
|
-
end
|
59
|
-
|
60
|
-
it "passes the block to the second document" do
|
61
|
-
people.last.age.should eq(36)
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
context "when providing attributes" do
|
67
|
-
|
68
|
-
let(:person) do
|
69
|
-
Person.create(title: "Sensei")
|
70
|
-
end
|
71
|
-
|
72
|
-
it "it saves the document" do
|
73
|
-
person.should be_persisted
|
74
|
-
end
|
75
|
-
|
76
|
-
it "returns the document" do
|
77
|
-
person.should be_a_kind_of(Person)
|
78
|
-
end
|
79
|
-
|
80
|
-
context "when creating an embedded document" do
|
81
|
-
|
82
|
-
let(:address) do
|
83
|
-
Address.create(addressable: person)
|
84
|
-
end
|
85
|
-
|
86
|
-
it "persists the document" do
|
87
|
-
address.should be_persisted
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
context "when creating an embedded document with store_as option" do
|
92
|
-
|
93
|
-
let(:user) do
|
94
|
-
User.create
|
95
|
-
end
|
96
|
-
|
97
|
-
before(:all) do
|
98
|
-
User.embeds_many(
|
99
|
-
:addresses,
|
100
|
-
class_name: "Address",
|
101
|
-
store_as: "user_adresses",
|
102
|
-
validate: false
|
103
|
-
)
|
104
|
-
Address.embedded_in :user
|
105
|
-
end
|
106
|
-
|
107
|
-
before do
|
108
|
-
user.addresses.create!(city: "nantes")
|
109
|
-
end
|
110
|
-
|
111
|
-
let(:document) do
|
112
|
-
user.collection.find(_id: user.id).first
|
113
|
-
end
|
114
|
-
|
115
|
-
it "should not persist in address key on User document" do
|
116
|
-
document.keys.should_not include("addresses")
|
117
|
-
end
|
118
|
-
|
119
|
-
it "should persist on user_addesses key on User document" do
|
120
|
-
document.keys.should include("user_adresses")
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
|
-
|
125
|
-
context "when passing in a block" do
|
126
|
-
|
127
|
-
let(:person) do
|
128
|
-
Person.create do |peep|
|
129
|
-
peep.ssn = "666-66-6666"
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
|
-
it "sets the attributes" do
|
134
|
-
person.ssn.should eq("666-66-6666")
|
135
|
-
end
|
136
|
-
|
137
|
-
it "persists the document" do
|
138
|
-
person.should be_persisted
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
context "when mass assignment role is indicated" do
|
143
|
-
|
144
|
-
context "when attributes assigned from default role" do
|
145
|
-
|
146
|
-
let(:item) do
|
147
|
-
Item.create(
|
148
|
-
title: "Some Title",
|
149
|
-
is_rss: true,
|
150
|
-
user_login: "SomeLogin"
|
151
|
-
)
|
152
|
-
end
|
153
|
-
|
154
|
-
it "sets the field for the default role" do
|
155
|
-
item.is_rss.should be_true
|
156
|
-
end
|
157
|
-
|
158
|
-
it "does not set the field for non default role title" do
|
159
|
-
item.title.should be_nil
|
160
|
-
end
|
161
|
-
|
162
|
-
it "does not set the field for non default role user login" do
|
163
|
-
item.user_login.should be_nil
|
164
|
-
end
|
165
|
-
end
|
166
|
-
|
167
|
-
context "when attributes assigned from parser role" do
|
168
|
-
|
169
|
-
let(:item) do
|
170
|
-
Item.create(
|
171
|
-
{ title: "Some Title",
|
172
|
-
is_rss: true,
|
173
|
-
user_login: "SomeLogin" }, as: :parser
|
174
|
-
)
|
175
|
-
end
|
176
|
-
|
177
|
-
it "sets the user login field for parser role" do
|
178
|
-
item.user_login.should eq("SomeLogin")
|
179
|
-
end
|
180
|
-
|
181
|
-
it "sets the is rss field for parse role" do
|
182
|
-
item.is_rss.should be_false
|
183
|
-
end
|
184
|
-
|
185
|
-
it "does not set the title field" do
|
186
|
-
item.title.should be_nil
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context "when attributes assigned without protection" do
|
191
|
-
|
192
|
-
let(:item) do
|
193
|
-
Item.create(
|
194
|
-
{ title: "Some Title",
|
195
|
-
is_rss: true,
|
196
|
-
user_login: "SomeLogin"
|
197
|
-
}, without_protection: true
|
198
|
-
)
|
199
|
-
end
|
200
|
-
|
201
|
-
it "sets the title attribute" do
|
202
|
-
item.title.should eq("Some Title")
|
203
|
-
end
|
204
|
-
|
205
|
-
it "sets the user login attribute" do
|
206
|
-
item.user_login.should eq("SomeLogin")
|
207
|
-
end
|
208
|
-
|
209
|
-
it "sets the rss attribute" do
|
210
|
-
item.is_rss.should be_true
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
|
216
|
-
describe ".create!" do
|
217
|
-
|
218
|
-
context "when provided an array of attributes" do
|
219
|
-
|
220
|
-
context "when no block is passed" do
|
221
|
-
|
222
|
-
let(:people) do
|
223
|
-
Person.create!([{ title: "sir" }, { title: "madam" }])
|
224
|
-
end
|
225
|
-
|
226
|
-
it "creates the first document" do
|
227
|
-
people.first.title.should eq("sir")
|
228
|
-
end
|
229
|
-
|
230
|
-
it "persists the first document" do
|
231
|
-
people.first.should be_persisted
|
232
|
-
end
|
233
|
-
|
234
|
-
it "creates the second document" do
|
235
|
-
people.last.title.should eq("madam")
|
236
|
-
end
|
237
|
-
|
238
|
-
it "persists the second document" do
|
239
|
-
people.last.should be_persisted
|
240
|
-
end
|
241
|
-
end
|
242
|
-
|
243
|
-
context "when no block is passed" do
|
244
|
-
|
245
|
-
let(:people) do
|
246
|
-
Person.create!([{ title: "sir" }, { title: "madam" }]) do |person|
|
247
|
-
person.age = 36
|
248
|
-
end
|
249
|
-
end
|
250
|
-
|
251
|
-
it "creates the first document" do
|
252
|
-
people.first.title.should eq("sir")
|
253
|
-
end
|
254
|
-
|
255
|
-
it "persists the first document" do
|
256
|
-
people.first.should be_persisted
|
257
|
-
end
|
258
|
-
|
259
|
-
it "passes the block to the first document" do
|
260
|
-
people.first.age.should eq(36)
|
261
|
-
end
|
262
|
-
|
263
|
-
it "creates the second document" do
|
264
|
-
people.last.title.should eq("madam")
|
265
|
-
end
|
266
|
-
|
267
|
-
it "persists the second document" do
|
268
|
-
people.last.should be_persisted
|
269
|
-
end
|
270
|
-
|
271
|
-
it "passes the block to the second document" do
|
272
|
-
people.last.age.should eq(36)
|
273
|
-
end
|
274
|
-
end
|
275
|
-
end
|
276
|
-
|
277
|
-
context "inserting with a field that is not unique" do
|
278
|
-
|
279
|
-
context "when a unique index exists" do
|
280
|
-
|
281
|
-
before do
|
282
|
-
Person.create_indexes
|
283
|
-
end
|
284
|
-
|
285
|
-
it "raises an error" do
|
286
|
-
expect {
|
287
|
-
4.times { Person.with(safe: true).create!(ssn: "555-55-1029") }
|
288
|
-
}.to raise_error
|
289
|
-
end
|
290
|
-
end
|
291
|
-
end
|
292
|
-
|
293
|
-
context "when passing in a block" do
|
294
|
-
|
295
|
-
let(:person) do
|
296
|
-
Person.create! do |peep|
|
297
|
-
peep.ssn = "666-66-6666"
|
298
|
-
end
|
299
|
-
end
|
300
|
-
|
301
|
-
it "sets the attributes" do
|
302
|
-
person.ssn.should eq("666-66-6666")
|
303
|
-
end
|
304
|
-
|
305
|
-
it "persists the document" do
|
306
|
-
person.should be_persisted
|
307
|
-
end
|
308
|
-
end
|
309
|
-
|
310
|
-
context "when setting the composite key" do
|
311
|
-
|
312
|
-
let(:account) do
|
313
|
-
Account.create!(name: "Hello")
|
314
|
-
end
|
315
|
-
|
316
|
-
it "saves the document" do
|
317
|
-
account.should be_persisted
|
318
|
-
end
|
319
|
-
end
|
320
|
-
|
321
|
-
context "when a callback returns false" do
|
322
|
-
|
323
|
-
it "raises a callback error" do
|
324
|
-
expect { Oscar.create! }.to raise_error(Mongoid::Errors::Callback)
|
325
|
-
end
|
326
|
-
end
|
327
|
-
|
328
|
-
context "when mass assignment role is indicated" do
|
329
|
-
|
330
|
-
context "when attributes assigned from default role" do
|
331
|
-
|
332
|
-
let(:item) do
|
333
|
-
Item.create!(
|
334
|
-
title: "Some Title",
|
335
|
-
is_rss: true,
|
336
|
-
user_login: "SomeLogin"
|
337
|
-
)
|
338
|
-
end
|
339
|
-
|
340
|
-
it "sets the field for the default role" do
|
341
|
-
item.is_rss.should be_true
|
342
|
-
end
|
343
|
-
|
344
|
-
it "does not set the field for non default role title" do
|
345
|
-
item.title.should be_nil
|
346
|
-
end
|
347
|
-
|
348
|
-
it "does not set the field for non default role user login" do
|
349
|
-
item.user_login.should be_nil
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
context "when attributes assigned from parser role" do
|
354
|
-
|
355
|
-
let(:item) do
|
356
|
-
Item.create!(
|
357
|
-
{ title: "Some Title",
|
358
|
-
is_rss: true,
|
359
|
-
user_login: "SomeLogin" }, as: :parser
|
360
|
-
)
|
361
|
-
end
|
362
|
-
|
363
|
-
it "sets the user login field for parser role" do
|
364
|
-
item.user_login.should eq("SomeLogin")
|
365
|
-
end
|
366
|
-
|
367
|
-
it "sets the is rss field for parse role" do
|
368
|
-
item.is_rss.should be_false
|
369
|
-
end
|
370
|
-
|
371
|
-
it "does not set the title field" do
|
372
|
-
item.title.should be_nil
|
373
|
-
end
|
374
|
-
end
|
375
|
-
|
376
|
-
context "when attributes assigned without protection" do
|
377
|
-
|
378
|
-
let(:item) do
|
379
|
-
Item.create!(
|
380
|
-
{ title: "Some Title",
|
381
|
-
is_rss: true,
|
382
|
-
user_login: "SomeLogin"
|
383
|
-
}, without_protection: true
|
384
|
-
)
|
385
|
-
end
|
386
|
-
|
387
|
-
it "sets the title attribute" do
|
388
|
-
item.title.should eq("Some Title")
|
389
|
-
end
|
390
|
-
|
391
|
-
it "sets the user login attribute" do
|
392
|
-
item.user_login.should eq("SomeLogin")
|
393
|
-
end
|
394
|
-
|
395
|
-
it "sets the rss attribute" do
|
396
|
-
item.is_rss.should be_true
|
397
|
-
end
|
398
|
-
end
|
399
|
-
end
|
400
|
-
end
|
401
|
-
|
402
|
-
[ :delete, :destroy ].each do |method|
|
403
|
-
|
404
|
-
describe "##{method}" do
|
405
|
-
|
406
|
-
let(:person) do
|
407
|
-
Person.create
|
408
|
-
end
|
409
|
-
|
410
|
-
context "when removing a root document" do
|
411
|
-
|
412
|
-
let!(:deleted) do
|
413
|
-
person.send(method)
|
414
|
-
end
|
415
|
-
|
416
|
-
it "deletes the document from the collection" do
|
417
|
-
expect {
|
418
|
-
Person.find(person.id)
|
419
|
-
}.to raise_error
|
420
|
-
end
|
421
|
-
|
422
|
-
it "returns true" do
|
423
|
-
deleted.should be_true
|
424
|
-
end
|
425
|
-
|
426
|
-
it "resets the flagged for destroy flag" do
|
427
|
-
person.should_not be_flagged_for_destroy
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
|
-
context "when removing an embedded document" do
|
432
|
-
|
433
|
-
let(:address) do
|
434
|
-
person.addresses.build(street: "Bond Street")
|
435
|
-
end
|
436
|
-
|
437
|
-
context "when the document is not yet saved" do
|
438
|
-
|
439
|
-
before do
|
440
|
-
address.send(method)
|
441
|
-
end
|
442
|
-
|
443
|
-
it "removes the document from the parent" do
|
444
|
-
person.addresses.should be_empty
|
445
|
-
end
|
446
|
-
|
447
|
-
it "removes the attributes from the parent" do
|
448
|
-
person.raw_attributes["addresses"].should be_nil
|
449
|
-
end
|
450
|
-
|
451
|
-
it "resets the flagged for destroy flag" do
|
452
|
-
address.should_not be_flagged_for_destroy
|
453
|
-
end
|
454
|
-
end
|
455
|
-
|
456
|
-
context "when the document has been saved" do
|
457
|
-
|
458
|
-
before do
|
459
|
-
address.save
|
460
|
-
address.send(method)
|
461
|
-
end
|
462
|
-
|
463
|
-
let(:from_db) do
|
464
|
-
Person.find(person.id)
|
465
|
-
end
|
466
|
-
|
467
|
-
it "removes the object from the parent and database" do
|
468
|
-
from_db.addresses.should be_empty
|
469
|
-
end
|
470
|
-
end
|
471
|
-
end
|
472
|
-
|
473
|
-
context "when removing deeply embedded documents" do
|
474
|
-
|
475
|
-
context "when the document has been saved" do
|
476
|
-
|
477
|
-
let(:address) do
|
478
|
-
person.addresses.create(street: "Bond Street")
|
479
|
-
end
|
480
|
-
|
481
|
-
let(:location) do
|
482
|
-
address.locations.create(name: "Home")
|
483
|
-
end
|
484
|
-
|
485
|
-
let(:from_db) do
|
486
|
-
Person.find(person.id)
|
487
|
-
end
|
488
|
-
|
489
|
-
before do
|
490
|
-
location.send(method)
|
491
|
-
end
|
492
|
-
|
493
|
-
it "removes the object from the parent and database" do
|
494
|
-
from_db.addresses.first.locations.should be_empty
|
495
|
-
end
|
496
|
-
|
497
|
-
it "resets the flagged for destroy flag" do
|
498
|
-
location.should_not be_flagged_for_destroy
|
499
|
-
end
|
500
|
-
end
|
501
|
-
end
|
502
|
-
end
|
503
|
-
end
|
504
|
-
|
505
|
-
describe "#save" do
|
506
|
-
|
507
|
-
let(:person) do
|
508
|
-
Person.create
|
509
|
-
end
|
510
|
-
|
511
|
-
context "when skipping validation" do
|
512
|
-
|
513
|
-
context "when no relations are involved" do
|
514
|
-
|
515
|
-
let(:account) do
|
516
|
-
Account.new
|
517
|
-
end
|
518
|
-
|
519
|
-
let!(:saved) do
|
520
|
-
account.save(validate: false)
|
521
|
-
end
|
522
|
-
|
523
|
-
it "returns true" do
|
524
|
-
saved.should be_true
|
525
|
-
end
|
526
|
-
|
527
|
-
it "saves the document" do
|
528
|
-
account.should be_persisted
|
529
|
-
end
|
530
|
-
|
531
|
-
it "does not add any validation errors" do
|
532
|
-
account.errors.should be_empty
|
533
|
-
end
|
534
|
-
end
|
535
|
-
|
536
|
-
context "when saving document that is a belongs to child" do
|
537
|
-
|
538
|
-
let(:account) do
|
539
|
-
Account.create
|
540
|
-
end
|
541
|
-
|
542
|
-
let(:alert) do
|
543
|
-
Alert.new(account: account)
|
544
|
-
end
|
545
|
-
|
546
|
-
context "when validating presence of the parent" do
|
547
|
-
|
548
|
-
before do
|
549
|
-
Alert.validates(:message, :account, presence: true)
|
550
|
-
end
|
551
|
-
|
552
|
-
after do
|
553
|
-
Alert.reset_callbacks(:validate)
|
554
|
-
end
|
555
|
-
|
556
|
-
context "when the parent validates associated on the child" do
|
557
|
-
|
558
|
-
before do
|
559
|
-
alert.save(validate: false)
|
560
|
-
end
|
561
|
-
|
562
|
-
it "clears any errors off the document" do
|
563
|
-
alert.errors.should be_empty
|
564
|
-
end
|
565
|
-
|
566
|
-
context "when the document is not new" do
|
567
|
-
|
568
|
-
before do
|
569
|
-
alert.save(validate: false)
|
570
|
-
end
|
571
|
-
|
572
|
-
it "clears any errors off the document" do
|
573
|
-
alert.errors.should be_empty
|
574
|
-
end
|
575
|
-
end
|
576
|
-
end
|
577
|
-
end
|
578
|
-
end
|
579
|
-
end
|
580
|
-
|
581
|
-
context "when the document has been instantiated with limited fields" do
|
582
|
-
|
583
|
-
before do
|
584
|
-
person.age = 20
|
585
|
-
person.save
|
586
|
-
end
|
587
|
-
|
588
|
-
context "when a default is excluded" do
|
589
|
-
|
590
|
-
let(:limited) do
|
591
|
-
Person.only(:_id).find(person.id)
|
592
|
-
end
|
593
|
-
|
594
|
-
it "does not flag the excluded fields as dirty" do
|
595
|
-
limited.changes.should be_empty
|
596
|
-
end
|
597
|
-
|
598
|
-
it "does not overwrite with the default" do
|
599
|
-
limited.save
|
600
|
-
limited.reload.age.should eq(20)
|
601
|
-
end
|
602
|
-
end
|
603
|
-
|
604
|
-
context "when iterating over the documents" do
|
605
|
-
|
606
|
-
let(:limited) do
|
607
|
-
Person.only(:_id)
|
608
|
-
end
|
609
|
-
|
610
|
-
it "does not flag any changes" do
|
611
|
-
limited.each do |person|
|
612
|
-
person.changes.should be_empty
|
613
|
-
end
|
614
|
-
end
|
615
|
-
end
|
616
|
-
end
|
617
|
-
|
618
|
-
context "when validation passes" do
|
619
|
-
|
620
|
-
it "returns true" do
|
621
|
-
person.save.should be_true
|
622
|
-
end
|
623
|
-
end
|
624
|
-
|
625
|
-
context "when validation fails" do
|
626
|
-
|
627
|
-
let(:address) do
|
628
|
-
person.addresses.create(city: "London")
|
629
|
-
end
|
630
|
-
|
631
|
-
before do
|
632
|
-
address.save
|
633
|
-
end
|
634
|
-
|
635
|
-
it "has the appropriate errors" do
|
636
|
-
address.errors[:street].should eq(["can't be blank"])
|
637
|
-
end
|
638
|
-
end
|
639
|
-
|
640
|
-
context "when modifying the entire hierarchy" do
|
641
|
-
|
642
|
-
context "when performing modification and insert ops" do
|
643
|
-
|
644
|
-
let(:person) do
|
645
|
-
Person.create(title: "Blah")
|
646
|
-
end
|
647
|
-
|
648
|
-
let!(:address) do
|
649
|
-
person.addresses.build(street: "Bond St")
|
650
|
-
end
|
651
|
-
|
652
|
-
let!(:name) do
|
653
|
-
person.create_name(first_name: "Tony")
|
654
|
-
end
|
655
|
-
|
656
|
-
let(:from_db) do
|
657
|
-
Person.find(person.id)
|
658
|
-
end
|
659
|
-
|
660
|
-
before do
|
661
|
-
person.title = "King"
|
662
|
-
name.first_name = "Ryan"
|
663
|
-
end
|
664
|
-
|
665
|
-
it "persists with proper set and push modifiers" do
|
666
|
-
person.atomic_updates.should eq({
|
667
|
-
"$set" => {
|
668
|
-
"title" => "King",
|
669
|
-
"name.first_name" => "Ryan"
|
670
|
-
},
|
671
|
-
"$pushAll"=> {
|
672
|
-
"addresses" => [ { "_id" => address.id, "street" => "Bond St" } ]
|
673
|
-
}
|
674
|
-
})
|
675
|
-
end
|
676
|
-
|
677
|
-
context "when saving the document" do
|
678
|
-
|
679
|
-
it "saves the root document" do
|
680
|
-
person.title.should eq("King")
|
681
|
-
end
|
682
|
-
|
683
|
-
it "saves embedded many relations" do
|
684
|
-
person.addresses.first.street.should eq("Bond St")
|
685
|
-
end
|
686
|
-
|
687
|
-
it "saves embedded one relations" do
|
688
|
-
person.name.first_name.should eq("Ryan")
|
689
|
-
end
|
690
|
-
end
|
691
|
-
end
|
692
|
-
|
693
|
-
context "when combining modifications and pushes" do
|
694
|
-
|
695
|
-
let!(:location) do
|
696
|
-
Location.new(name: 'Work')
|
697
|
-
end
|
698
|
-
|
699
|
-
let!(:address) do
|
700
|
-
Address.new(
|
701
|
-
number: 101,
|
702
|
-
street: 'South St',
|
703
|
-
locations: [ location ]
|
704
|
-
)
|
705
|
-
end
|
706
|
-
|
707
|
-
let!(:person) do
|
708
|
-
Person.create(
|
709
|
-
title: "Blah",
|
710
|
-
addresses: [ address ]
|
711
|
-
)
|
712
|
-
end
|
713
|
-
|
714
|
-
let(:from_db) do
|
715
|
-
Person.find(person.id)
|
716
|
-
end
|
717
|
-
|
718
|
-
before do
|
719
|
-
address.number = 102
|
720
|
-
person.addresses << Address.new(street: "North Ave")
|
721
|
-
person.save
|
722
|
-
end
|
723
|
-
|
724
|
-
it "saves modifications to existing embedded docs" do
|
725
|
-
from_db.addresses[0].number.should eq(102)
|
726
|
-
end
|
727
|
-
|
728
|
-
it "saves modifications to new embedded docs" do
|
729
|
-
from_db.addresses[1].street.should eq('North Ave')
|
730
|
-
end
|
731
|
-
|
732
|
-
it "saves modifications to deeply embedded docs" do
|
733
|
-
from_db.addresses[0].locations.first.name.should eq('Work')
|
734
|
-
end
|
735
|
-
end
|
736
|
-
|
737
|
-
context "when removing elements without using delete or destroy" do
|
738
|
-
|
739
|
-
let!(:person) do
|
740
|
-
Person.create!(title: "Blah")
|
741
|
-
end
|
742
|
-
|
743
|
-
let(:from_db) do
|
744
|
-
Person.find(person.id)
|
745
|
-
end
|
746
|
-
|
747
|
-
before do
|
748
|
-
person.create_name(first_name: "Tony")
|
749
|
-
person.name = nil
|
750
|
-
person.save
|
751
|
-
end
|
752
|
-
|
753
|
-
it "saves the hierarchy" do
|
754
|
-
person.name.should be_nil
|
755
|
-
end
|
756
|
-
end
|
757
|
-
end
|
758
|
-
end
|
759
|
-
|
760
|
-
describe "save!" do
|
761
|
-
|
762
|
-
context "inserting with a field that is not unique" do
|
763
|
-
|
764
|
-
context "when a unique index exists" do
|
765
|
-
|
766
|
-
let(:person) do
|
767
|
-
Person.new(ssn: "555-55-9999")
|
768
|
-
end
|
769
|
-
|
770
|
-
before do
|
771
|
-
Person.create_indexes
|
772
|
-
Person.create!(ssn: "555-55-9999")
|
773
|
-
end
|
774
|
-
|
775
|
-
it "raises an error" do
|
776
|
-
expect { person.with(safe: true).save! }.to raise_error
|
777
|
-
end
|
778
|
-
end
|
779
|
-
end
|
780
|
-
|
781
|
-
context "with a validation error" do
|
782
|
-
|
783
|
-
let(:person) do
|
784
|
-
Person.new
|
785
|
-
end
|
786
|
-
|
787
|
-
let!(:service) do
|
788
|
-
Service.new(person: person, sid: "a")
|
789
|
-
end
|
790
|
-
|
791
|
-
it "raises an error with multiple save attempts" do
|
792
|
-
expect { subject.save! }.to raise_error
|
793
|
-
expect { subject.save! }.to raise_error
|
794
|
-
end
|
795
|
-
end
|
796
|
-
|
797
|
-
context "when a callback returns false" do
|
798
|
-
|
799
|
-
let(:oscar) do
|
800
|
-
Oscar.new
|
801
|
-
end
|
802
|
-
|
803
|
-
it "raises a callback error" do
|
804
|
-
expect { oscar.save! }.to raise_error(Mongoid::Errors::Callback)
|
805
|
-
end
|
806
|
-
end
|
807
|
-
|
808
|
-
context "when a callback destroys the document" do
|
809
|
-
|
810
|
-
let(:oscar) do
|
811
|
-
Oscar.new(:destroy_after_save => true)
|
812
|
-
end
|
813
|
-
|
814
|
-
before do
|
815
|
-
oscar.save!
|
816
|
-
end
|
817
|
-
|
818
|
-
it "flags the document as destroyed" do
|
819
|
-
oscar.should be_destroyed
|
820
|
-
end
|
821
|
-
end
|
822
|
-
end
|
823
|
-
|
824
|
-
describe "#touch" do
|
825
|
-
|
826
|
-
context "when the document is embedded" do
|
827
|
-
|
828
|
-
let(:band) do
|
829
|
-
Band.create(name: "Placebo")
|
830
|
-
end
|
831
|
-
|
832
|
-
let(:label) do
|
833
|
-
band.create_label(name: "Mute", updated_at: 10.days.ago)
|
834
|
-
end
|
835
|
-
|
836
|
-
before do
|
837
|
-
label.touch
|
838
|
-
end
|
839
|
-
|
840
|
-
it "updates the updated_at timestamp" do
|
841
|
-
label.updated_at.should be_within(1).of(Time.now)
|
842
|
-
end
|
843
|
-
|
844
|
-
it "persists the changes" do
|
845
|
-
label.reload.updated_at.should be_within(1).of(Time.now)
|
846
|
-
end
|
847
|
-
end
|
848
|
-
|
849
|
-
context "when no relations have touch options" do
|
850
|
-
|
851
|
-
context "when no updated at is defined" do
|
852
|
-
|
853
|
-
let(:person) do
|
854
|
-
Person.create
|
855
|
-
end
|
856
|
-
|
857
|
-
context "when no attribute is provided" do
|
858
|
-
|
859
|
-
let!(:touched) do
|
860
|
-
person.touch
|
861
|
-
end
|
862
|
-
|
863
|
-
it "returns true" do
|
864
|
-
touched.should be_true
|
865
|
-
end
|
866
|
-
|
867
|
-
it "does not set the updated at field" do
|
868
|
-
person[:updated_at].should be_nil
|
869
|
-
end
|
870
|
-
end
|
871
|
-
|
872
|
-
context "when an attribute is provided" do
|
873
|
-
|
874
|
-
let!(:touched) do
|
875
|
-
person.touch(:lunch_time)
|
876
|
-
end
|
877
|
-
|
878
|
-
it "sets the attribute to the current time" do
|
879
|
-
person.lunch_time.should be_within(5).of(Time.now)
|
880
|
-
end
|
881
|
-
|
882
|
-
it "persists the change" do
|
883
|
-
person.reload.lunch_time.should be_within(5).of(Time.now)
|
884
|
-
end
|
885
|
-
|
886
|
-
it "returns true" do
|
887
|
-
touched.should be_true
|
888
|
-
end
|
889
|
-
end
|
890
|
-
|
891
|
-
context "when an attribute alias is provided" do
|
892
|
-
|
893
|
-
let!(:touched) do
|
894
|
-
person.touch(:aliased_timestamp)
|
895
|
-
end
|
896
|
-
|
897
|
-
it "sets the attribute to the current time" do
|
898
|
-
person.aliased_timestamp.should be_within(5).of(Time.now)
|
899
|
-
end
|
900
|
-
|
901
|
-
it "persists the change" do
|
902
|
-
person.reload.aliased_timestamp.should be_within(5).of(Time.now)
|
903
|
-
end
|
904
|
-
|
905
|
-
it "returns true" do
|
906
|
-
touched.should be_true
|
907
|
-
end
|
908
|
-
end
|
909
|
-
end
|
910
|
-
|
911
|
-
context "when an updated at is defined" do
|
912
|
-
|
913
|
-
let!(:agent) do
|
914
|
-
Agent.create(updated_at: 2.days.ago)
|
915
|
-
end
|
916
|
-
|
917
|
-
context "when no attribute is provided" do
|
918
|
-
|
919
|
-
let!(:touched) do
|
920
|
-
agent.touch
|
921
|
-
end
|
922
|
-
|
923
|
-
it "sets the updated at to the current time" do
|
924
|
-
agent.updated_at.should be_within(5).of(Time.now)
|
925
|
-
end
|
926
|
-
|
927
|
-
it "persists the change" do
|
928
|
-
agent.reload.updated_at.should be_within(5).of(Time.now)
|
929
|
-
end
|
930
|
-
|
931
|
-
it "returns true" do
|
932
|
-
touched.should be_true
|
933
|
-
end
|
934
|
-
|
935
|
-
it "keeps changes for next callback" do
|
936
|
-
agent.changes.should_not be_empty
|
937
|
-
end
|
938
|
-
end
|
939
|
-
|
940
|
-
context "when an attribute is provided" do
|
941
|
-
|
942
|
-
let!(:touched) do
|
943
|
-
agent.touch(:dob)
|
944
|
-
end
|
945
|
-
|
946
|
-
it "sets the updated at to the current time" do
|
947
|
-
agent.updated_at.should be_within(5).of(Time.now)
|
948
|
-
end
|
949
|
-
|
950
|
-
it "sets the attribute to the current time" do
|
951
|
-
agent.dob.should be_within(5).of(Time.now)
|
952
|
-
end
|
953
|
-
|
954
|
-
it "sets both attributes to the exact same time" do
|
955
|
-
agent.updated_at.should eq(agent.dob)
|
956
|
-
end
|
957
|
-
|
958
|
-
it "persists the updated at change" do
|
959
|
-
agent.reload.updated_at.should be_within(5).of(Time.now)
|
960
|
-
end
|
961
|
-
|
962
|
-
it "persists the attribute change" do
|
963
|
-
agent.reload.dob.should be_within(5).of(Time.now)
|
964
|
-
end
|
965
|
-
|
966
|
-
it "returns true" do
|
967
|
-
touched.should be_true
|
968
|
-
end
|
969
|
-
|
970
|
-
it "keeps changes for next callback" do
|
971
|
-
agent.changes.should_not be_empty
|
972
|
-
end
|
973
|
-
end
|
974
|
-
end
|
975
|
-
|
976
|
-
context "when record is new" do
|
977
|
-
|
978
|
-
let(:agent) do
|
979
|
-
Agent.new(updated_at: 2.days.ago)
|
980
|
-
end
|
981
|
-
|
982
|
-
context "when no attribute is provided" do
|
983
|
-
|
984
|
-
let!(:touched) do
|
985
|
-
agent.touch
|
986
|
-
end
|
987
|
-
|
988
|
-
it "returns false" do
|
989
|
-
touched.should be_false
|
990
|
-
end
|
991
|
-
end
|
992
|
-
|
993
|
-
context "when an attribute is provided" do
|
994
|
-
|
995
|
-
let!(:touched) do
|
996
|
-
agent.touch(:dob)
|
997
|
-
end
|
998
|
-
|
999
|
-
it "returns false" do
|
1000
|
-
touched.should be_false
|
1001
|
-
end
|
1002
|
-
end
|
1003
|
-
end
|
1004
|
-
|
1005
|
-
context "when creating the child" do
|
1006
|
-
|
1007
|
-
let(:time) do
|
1008
|
-
Time.utc(2012, 4, 3, 12)
|
1009
|
-
end
|
1010
|
-
|
1011
|
-
let(:jar) do
|
1012
|
-
Jar.new(_id: 1, updated_at: time).tap do |jar|
|
1013
|
-
jar.save!
|
1014
|
-
end
|
1015
|
-
end
|
1016
|
-
|
1017
|
-
let!(:cookie) do
|
1018
|
-
jar.cookies.create!(updated_at: time)
|
1019
|
-
end
|
1020
|
-
|
1021
|
-
it "does not touch the parent" do
|
1022
|
-
jar.updated_at.should eq(time)
|
1023
|
-
end
|
1024
|
-
end
|
1025
|
-
end
|
1026
|
-
|
1027
|
-
context "when relations have touch options" do
|
1028
|
-
|
1029
|
-
context "when the relation is nil" do
|
1030
|
-
|
1031
|
-
let!(:agent) do
|
1032
|
-
Agent.create
|
1033
|
-
end
|
1034
|
-
|
1035
|
-
context "when the relation autobuilds" do
|
1036
|
-
|
1037
|
-
let!(:touched) do
|
1038
|
-
agent.touch
|
1039
|
-
end
|
1040
|
-
|
1041
|
-
it "does nothing to the relation" do
|
1042
|
-
agent.instance_variable_get(:@agency).should be_nil
|
1043
|
-
end
|
1044
|
-
end
|
1045
|
-
end
|
1046
|
-
|
1047
|
-
context "when the relation is not nil" do
|
1048
|
-
|
1049
|
-
let!(:agent) do
|
1050
|
-
Agent.create
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
let!(:agency) do
|
1054
|
-
agent.create_agency.tap do |a|
|
1055
|
-
a.unset(:updated_at)
|
1056
|
-
end
|
1057
|
-
end
|
1058
|
-
|
1059
|
-
let!(:touched) do
|
1060
|
-
agent.touch
|
1061
|
-
end
|
1062
|
-
|
1063
|
-
it "sets the parent updated at to the current time" do
|
1064
|
-
agency.updated_at.should be_within(5).of(Time.now)
|
1065
|
-
end
|
1066
|
-
|
1067
|
-
it "persists the change" do
|
1068
|
-
agency.reload.updated_at.should be_within(5).of(Time.now)
|
1069
|
-
end
|
1070
|
-
end
|
1071
|
-
|
1072
|
-
context "when creating the child" do
|
1073
|
-
|
1074
|
-
let!(:agency) do
|
1075
|
-
Agency.create
|
1076
|
-
end
|
1077
|
-
|
1078
|
-
let!(:updated) do
|
1079
|
-
agency.updated_at
|
1080
|
-
end
|
1081
|
-
|
1082
|
-
let!(:agent) do
|
1083
|
-
agency.agents.create
|
1084
|
-
end
|
1085
|
-
|
1086
|
-
it "updates the parent's updated at" do
|
1087
|
-
agency.updated_at.should_not eq(updated)
|
1088
|
-
end
|
1089
|
-
end
|
1090
|
-
|
1091
|
-
context "when destroying the child" do
|
1092
|
-
|
1093
|
-
let!(:agency) do
|
1094
|
-
Agency.create
|
1095
|
-
end
|
1096
|
-
|
1097
|
-
let!(:agent) do
|
1098
|
-
agency.agents.create
|
1099
|
-
end
|
1100
|
-
|
1101
|
-
let!(:updated) do
|
1102
|
-
agency.updated_at
|
1103
|
-
end
|
1104
|
-
|
1105
|
-
before do
|
1106
|
-
agent.destroy
|
1107
|
-
end
|
1108
|
-
|
1109
|
-
it "updates the parent's updated at" do
|
1110
|
-
agency.updated_at.should_not eq(updated)
|
1111
|
-
end
|
1112
|
-
end
|
1113
|
-
end
|
1114
|
-
end
|
1115
|
-
|
1116
|
-
describe "#update_attribute" do
|
1117
|
-
|
1118
|
-
context "when the field is aliased" do
|
1119
|
-
|
1120
|
-
let(:person) do
|
1121
|
-
Person.create
|
1122
|
-
end
|
1123
|
-
|
1124
|
-
context "when setting via the field name" do
|
1125
|
-
|
1126
|
-
before do
|
1127
|
-
person.update_attribute(:t, "testing")
|
1128
|
-
end
|
1129
|
-
|
1130
|
-
it "updates the field" do
|
1131
|
-
person.t.should eq("testing")
|
1132
|
-
end
|
1133
|
-
|
1134
|
-
it "persists the changes" do
|
1135
|
-
person.reload.t.should eq("testing")
|
1136
|
-
end
|
1137
|
-
end
|
1138
|
-
|
1139
|
-
context "when setting via the field alias" do
|
1140
|
-
|
1141
|
-
before do
|
1142
|
-
person.update_attribute(:test, "testing")
|
1143
|
-
end
|
1144
|
-
|
1145
|
-
it "updates the field" do
|
1146
|
-
person.t.should eq("testing")
|
1147
|
-
end
|
1148
|
-
|
1149
|
-
it "persists the changes" do
|
1150
|
-
person.reload.t.should eq("testing")
|
1151
|
-
end
|
1152
|
-
end
|
1153
|
-
end
|
1154
|
-
|
1155
|
-
context "when setting an array field" do
|
1156
|
-
|
1157
|
-
let(:person) do
|
1158
|
-
Person.create(aliases: [])
|
1159
|
-
end
|
1160
|
-
|
1161
|
-
before do
|
1162
|
-
person.update_attribute(:aliases, person.aliases << "Bond")
|
1163
|
-
end
|
1164
|
-
|
1165
|
-
it "sets the new value in the document" do
|
1166
|
-
person.aliases.should eq([ "Bond" ])
|
1167
|
-
end
|
1168
|
-
|
1169
|
-
it "persists the changes" do
|
1170
|
-
person.reload.aliases.should eq([ "Bond" ])
|
1171
|
-
end
|
1172
|
-
end
|
1173
|
-
|
1174
|
-
context "when setting a boolean field" do
|
1175
|
-
|
1176
|
-
context "when the field is true" do
|
1177
|
-
|
1178
|
-
let(:person) do
|
1179
|
-
Person.new(terms: true)
|
1180
|
-
end
|
1181
|
-
|
1182
|
-
context "when setting to false" do
|
1183
|
-
|
1184
|
-
before do
|
1185
|
-
person.update_attribute(:terms, false)
|
1186
|
-
end
|
1187
|
-
|
1188
|
-
it "persists the document" do
|
1189
|
-
person.should be_persisted
|
1190
|
-
end
|
1191
|
-
|
1192
|
-
it "changes the attribute value" do
|
1193
|
-
person.terms.should be_false
|
1194
|
-
end
|
1195
|
-
|
1196
|
-
it "persists the changes" do
|
1197
|
-
person.reload.terms.should be_false
|
1198
|
-
end
|
1199
|
-
end
|
1200
|
-
end
|
1201
|
-
end
|
1202
|
-
|
1203
|
-
context "when provided a symbol attribute name" do
|
1204
|
-
|
1205
|
-
let(:post) do
|
1206
|
-
Post.new
|
1207
|
-
end
|
1208
|
-
|
1209
|
-
context "when the document is valid" do
|
1210
|
-
|
1211
|
-
before do
|
1212
|
-
post.update_attribute(:title, "Testing")
|
1213
|
-
end
|
1214
|
-
|
1215
|
-
it "sets the attribute" do
|
1216
|
-
post.title.should eq("Testing")
|
1217
|
-
end
|
1218
|
-
|
1219
|
-
it "saves the document" do
|
1220
|
-
post.should be_persisted
|
1221
|
-
end
|
1222
|
-
end
|
1223
|
-
|
1224
|
-
context "when updating to the same value" do
|
1225
|
-
|
1226
|
-
before do
|
1227
|
-
post.update_attribute(:title, "Testing")
|
1228
|
-
end
|
1229
|
-
|
1230
|
-
it "returns true" do
|
1231
|
-
post.update_attribute(:title, "Testing").should be_true
|
1232
|
-
end
|
1233
|
-
end
|
1234
|
-
|
1235
|
-
context "when the document is invalid" do
|
1236
|
-
|
1237
|
-
before do
|
1238
|
-
post.update_attribute(:title, "$invalid")
|
1239
|
-
end
|
1240
|
-
|
1241
|
-
it "sets the attribute" do
|
1242
|
-
post.title.should eq("$invalid")
|
1243
|
-
end
|
1244
|
-
|
1245
|
-
it "saves the document" do
|
1246
|
-
post.should be_persisted
|
1247
|
-
end
|
1248
|
-
end
|
1249
|
-
|
1250
|
-
context "when the document has been destroyed" do
|
1251
|
-
|
1252
|
-
before do
|
1253
|
-
post.delete
|
1254
|
-
end
|
1255
|
-
|
1256
|
-
it "raises an error" do
|
1257
|
-
expect {
|
1258
|
-
post.update_attribute(:title, "something")
|
1259
|
-
}.to raise_error
|
1260
|
-
end
|
1261
|
-
end
|
1262
|
-
end
|
1263
|
-
|
1264
|
-
context "when provided a string attribute name" do
|
1265
|
-
|
1266
|
-
let(:post) do
|
1267
|
-
Post.new
|
1268
|
-
end
|
1269
|
-
|
1270
|
-
context "when the document is valid" do
|
1271
|
-
|
1272
|
-
before do
|
1273
|
-
post.update_attribute("title", "Testing")
|
1274
|
-
end
|
1275
|
-
|
1276
|
-
it "sets the attribute" do
|
1277
|
-
post.title.should eq("Testing")
|
1278
|
-
end
|
1279
|
-
|
1280
|
-
it "saves the document" do
|
1281
|
-
post.should be_persisted
|
1282
|
-
end
|
1283
|
-
end
|
1284
|
-
|
1285
|
-
context "when the document is invalid" do
|
1286
|
-
|
1287
|
-
before do
|
1288
|
-
post.update_attribute("title", "$invalid")
|
1289
|
-
end
|
1290
|
-
|
1291
|
-
it "sets the attribute" do
|
1292
|
-
post.title.should eq("$invalid")
|
1293
|
-
end
|
1294
|
-
|
1295
|
-
it "saves the document" do
|
1296
|
-
post.should be_persisted
|
1297
|
-
end
|
1298
|
-
end
|
1299
|
-
end
|
1300
|
-
|
1301
|
-
context "when persisting a localized field" do
|
1302
|
-
|
1303
|
-
let!(:product) do
|
1304
|
-
Product.create(description: "The bomb")
|
1305
|
-
end
|
1306
|
-
|
1307
|
-
before do
|
1308
|
-
::I18n.locale = :de
|
1309
|
-
product.update_attribute(:description, "Die Bombe")
|
1310
|
-
end
|
1311
|
-
|
1312
|
-
after do
|
1313
|
-
::I18n.locale = :en
|
1314
|
-
end
|
1315
|
-
|
1316
|
-
let(:attributes) do
|
1317
|
-
product.attributes["description"]
|
1318
|
-
end
|
1319
|
-
|
1320
|
-
it "persists the en locale" do
|
1321
|
-
attributes["en"].should eq("The bomb")
|
1322
|
-
end
|
1323
|
-
|
1324
|
-
it "persists the de locale" do
|
1325
|
-
attributes["de"].should eq("Die Bombe")
|
1326
|
-
end
|
1327
|
-
end
|
1328
|
-
|
1329
|
-
context "when updating a deeply embedded document" do
|
1330
|
-
|
1331
|
-
let!(:person) do
|
1332
|
-
Person.create
|
1333
|
-
end
|
1334
|
-
|
1335
|
-
let!(:address) do
|
1336
|
-
person.addresses.create(street: "Winterfeldtstr")
|
1337
|
-
end
|
1338
|
-
|
1339
|
-
let!(:location) do
|
1340
|
-
address.locations.create(name: "work")
|
1341
|
-
end
|
1342
|
-
|
1343
|
-
let(:from_db) do
|
1344
|
-
Person.last.addresses.last.locations.last
|
1345
|
-
end
|
1346
|
-
|
1347
|
-
before do
|
1348
|
-
from_db.update_attribute(:name, "home")
|
1349
|
-
end
|
1350
|
-
|
1351
|
-
it "updates the attribute" do
|
1352
|
-
from_db.name.should eq("home")
|
1353
|
-
end
|
1354
|
-
|
1355
|
-
it "persists the changes" do
|
1356
|
-
from_db.reload.name.should eq("home")
|
1357
|
-
end
|
1358
|
-
end
|
1359
|
-
end
|
1360
|
-
|
1361
|
-
describe "#update_attributes" do
|
1362
|
-
|
1363
|
-
context "when providing options" do
|
1364
|
-
|
1365
|
-
let(:person) do
|
1366
|
-
Person.create
|
1367
|
-
end
|
1368
|
-
|
1369
|
-
let(:params) do
|
1370
|
-
[{ pets: false }, { as: :default }]
|
1371
|
-
end
|
1372
|
-
|
1373
|
-
it "accepts the additional parameter" do
|
1374
|
-
expect {
|
1375
|
-
person.update_attributes(*params)
|
1376
|
-
}.to_not raise_error(ArgumentError)
|
1377
|
-
end
|
1378
|
-
|
1379
|
-
it "calls assign_attributes" do
|
1380
|
-
person.should_receive(:assign_attributes).with(*params)
|
1381
|
-
person.update_attributes(*params)
|
1382
|
-
end
|
1383
|
-
|
1384
|
-
end
|
1385
|
-
|
1386
|
-
context "when saving with a hash field with invalid keys" do
|
1387
|
-
|
1388
|
-
let(:person) do
|
1389
|
-
Person.create
|
1390
|
-
end
|
1391
|
-
|
1392
|
-
it "raises an error" do
|
1393
|
-
expect {
|
1394
|
-
person.with(safe: true).update_attributes(map: { "bad.key" => "value" })
|
1395
|
-
}.to raise_error(Moped::Errors::OperationFailure)
|
1396
|
-
end
|
1397
|
-
end
|
1398
|
-
|
1399
|
-
context "when validation passes" do
|
1400
|
-
|
1401
|
-
let(:person) do
|
1402
|
-
Person.create
|
1403
|
-
end
|
1404
|
-
|
1405
|
-
let!(:saved) do
|
1406
|
-
person.update_attributes(pets: false)
|
1407
|
-
end
|
1408
|
-
|
1409
|
-
let(:from_db) do
|
1410
|
-
Person.find(person.id)
|
1411
|
-
end
|
1412
|
-
|
1413
|
-
it "returns true" do
|
1414
|
-
saved.should be_true
|
1415
|
-
end
|
1416
|
-
|
1417
|
-
it "saves the attributes" do
|
1418
|
-
from_db.pets.should be_false
|
1419
|
-
end
|
1420
|
-
end
|
1421
|
-
|
1422
|
-
context "when the document has been destroyed" do
|
1423
|
-
|
1424
|
-
let!(:person) do
|
1425
|
-
Person.create
|
1426
|
-
end
|
1427
|
-
|
1428
|
-
before do
|
1429
|
-
person.delete
|
1430
|
-
end
|
1431
|
-
|
1432
|
-
it "raises an error" do
|
1433
|
-
expect {
|
1434
|
-
person.update_attributes(title: "something")
|
1435
|
-
}.to raise_error
|
1436
|
-
end
|
1437
|
-
end
|
1438
|
-
|
1439
|
-
context "when updating through a one-to-one relation" do
|
1440
|
-
|
1441
|
-
let(:person) do
|
1442
|
-
Person.create!
|
1443
|
-
end
|
1444
|
-
|
1445
|
-
let(:game) do
|
1446
|
-
Game.create(person: person)
|
1447
|
-
end
|
1448
|
-
|
1449
|
-
before do
|
1450
|
-
person.update_attributes!(ssn: "444-44-4444")
|
1451
|
-
game.person.update_attributes!(ssn: "555-66-7777")
|
1452
|
-
end
|
1453
|
-
|
1454
|
-
let(:from_db) do
|
1455
|
-
Person.find(person.id)
|
1456
|
-
end
|
1457
|
-
|
1458
|
-
it "saves the attributes" do
|
1459
|
-
person.ssn.should eq("555-66-7777")
|
1460
|
-
end
|
1461
|
-
end
|
1462
|
-
|
1463
|
-
context "on a new record" do
|
1464
|
-
|
1465
|
-
let(:person) do
|
1466
|
-
Person.new
|
1467
|
-
end
|
1468
|
-
|
1469
|
-
before do
|
1470
|
-
person.update_attributes(pets: false, title: nil)
|
1471
|
-
end
|
1472
|
-
|
1473
|
-
it "saves the new record" do
|
1474
|
-
Person.find(person.id).should_not be_nil
|
1475
|
-
end
|
1476
|
-
end
|
1477
|
-
|
1478
|
-
context "when passing in a relation" do
|
1479
|
-
|
1480
|
-
context "when providing an embedded child" do
|
1481
|
-
|
1482
|
-
let!(:person) do
|
1483
|
-
Person.create
|
1484
|
-
end
|
1485
|
-
|
1486
|
-
let!(:name) do
|
1487
|
-
person.create_name(first_name: "test", last_name: "user")
|
1488
|
-
end
|
1489
|
-
|
1490
|
-
let(:new_name) do
|
1491
|
-
Name.new(first_name: "Rupert", last_name: "Parkes")
|
1492
|
-
end
|
1493
|
-
|
1494
|
-
before do
|
1495
|
-
person.update_attributes(name: new_name)
|
1496
|
-
end
|
1497
|
-
|
1498
|
-
it "updates the embedded document" do
|
1499
|
-
person.name.should eq(new_name)
|
1500
|
-
end
|
1501
|
-
|
1502
|
-
it "persists the changes" do
|
1503
|
-
person.reload.name.should eq(new_name)
|
1504
|
-
end
|
1505
|
-
end
|
1506
|
-
|
1507
|
-
context "when providing a parent to a referenced in" do
|
1508
|
-
|
1509
|
-
let!(:person) do
|
1510
|
-
Person.create
|
1511
|
-
end
|
1512
|
-
|
1513
|
-
let!(:post) do
|
1514
|
-
Post.create(title: "Testing")
|
1515
|
-
end
|
1516
|
-
|
1517
|
-
context "when the relation has not yet been touched" do
|
1518
|
-
|
1519
|
-
before do
|
1520
|
-
post.update_attributes(person: person)
|
1521
|
-
end
|
1522
|
-
|
1523
|
-
it "sets the instance of the relation" do
|
1524
|
-
person.posts.should eq([ post ])
|
1525
|
-
end
|
1526
|
-
|
1527
|
-
it "sets properly through method_missing" do
|
1528
|
-
person.posts.to_a.should eq([ post ])
|
1529
|
-
end
|
1530
|
-
|
1531
|
-
it "persists the reference" do
|
1532
|
-
person.posts(true).should eq([ post ])
|
1533
|
-
end
|
1534
|
-
end
|
1535
|
-
|
1536
|
-
context "when the relation has been touched" do
|
1537
|
-
|
1538
|
-
before do
|
1539
|
-
person.posts
|
1540
|
-
post.update_attributes(person: person)
|
1541
|
-
end
|
1542
|
-
|
1543
|
-
it "sets the instance of the relation" do
|
1544
|
-
person.posts.should eq([ post ])
|
1545
|
-
end
|
1546
|
-
|
1547
|
-
it "sets properly through method_missing" do
|
1548
|
-
person.posts.to_a.should eq([ post ])
|
1549
|
-
end
|
1550
|
-
|
1551
|
-
it "persists the reference" do
|
1552
|
-
person.posts(true).should eq([ post ])
|
1553
|
-
end
|
1554
|
-
end
|
1555
|
-
end
|
1556
|
-
end
|
1557
|
-
|
1558
|
-
context "when in a deeply nested hierarchy" do
|
1559
|
-
|
1560
|
-
let!(:person) do
|
1561
|
-
Person.new(title: "The Boss")
|
1562
|
-
end
|
1563
|
-
|
1564
|
-
let!(:phone_number) do
|
1565
|
-
Phone.new(number: "123-456-7890")
|
1566
|
-
end
|
1567
|
-
|
1568
|
-
let!(:country_code) do
|
1569
|
-
CountryCode.new(code: 1)
|
1570
|
-
end
|
1571
|
-
|
1572
|
-
before do
|
1573
|
-
phone_number.country_code = country_code
|
1574
|
-
person.phone_numbers << phone_number
|
1575
|
-
person.save
|
1576
|
-
end
|
1577
|
-
|
1578
|
-
it "sets the first level document" do
|
1579
|
-
person.phone_numbers.first.should eq(phone_number)
|
1580
|
-
end
|
1581
|
-
|
1582
|
-
it "sets the second level document" do
|
1583
|
-
person.phone_numbers.first.country_code.should eq(country_code)
|
1584
|
-
end
|
1585
|
-
|
1586
|
-
context "when updating the first level document" do
|
1587
|
-
|
1588
|
-
let(:phone) do
|
1589
|
-
person.phone_numbers.first
|
1590
|
-
end
|
1591
|
-
|
1592
|
-
before do
|
1593
|
-
phone.number = "098-765-4321"
|
1594
|
-
phone.update_attributes(number: "098-765-4321")
|
1595
|
-
end
|
1596
|
-
|
1597
|
-
it "sets the new attributes" do
|
1598
|
-
phone.number.should eq("098-765-4321")
|
1599
|
-
end
|
1600
|
-
|
1601
|
-
context "when reloading the root" do
|
1602
|
-
|
1603
|
-
let(:reloaded) do
|
1604
|
-
person.reload
|
1605
|
-
end
|
1606
|
-
|
1607
|
-
it "saves the new attributes" do
|
1608
|
-
reloaded.phone_numbers.first.number.should eq("098-765-4321")
|
1609
|
-
end
|
1610
|
-
end
|
1611
|
-
end
|
1612
|
-
end
|
1613
|
-
end
|
1614
|
-
|
1615
|
-
describe "#update_attributes!" do
|
1616
|
-
|
1617
|
-
context "when providing options" do
|
1618
|
-
|
1619
|
-
let(:person) do
|
1620
|
-
Person.create
|
1621
|
-
end
|
1622
|
-
|
1623
|
-
let(:params) do
|
1624
|
-
[{ pets: false }, { as: :default }]
|
1625
|
-
end
|
1626
|
-
|
1627
|
-
it "accepts the additional parameter" do
|
1628
|
-
expect {
|
1629
|
-
person.update_attributes!(*params)
|
1630
|
-
}.to_not raise_error(ArgumentError)
|
1631
|
-
end
|
1632
|
-
|
1633
|
-
it "calls assign_attributes" do
|
1634
|
-
person.should_receive(:assign_attributes).with(*params)
|
1635
|
-
person.update_attributes!(*params)
|
1636
|
-
end
|
1637
|
-
|
1638
|
-
end
|
1639
|
-
|
1640
|
-
context "when a callback returns false" do
|
1641
|
-
|
1642
|
-
let(:oscar) do
|
1643
|
-
Oscar.new
|
1644
|
-
end
|
1645
|
-
|
1646
|
-
it "raises a callback error" do
|
1647
|
-
expect {
|
1648
|
-
oscar.update_attributes!(title: "The Grouch")
|
1649
|
-
}.to raise_error(Mongoid::Errors::Callback)
|
1650
|
-
end
|
1651
|
-
end
|
1652
|
-
end
|
1653
|
-
|
1654
|
-
describe "#upsert" do
|
1655
|
-
|
1656
|
-
context "when the document validates on upsert" do
|
1657
|
-
|
1658
|
-
let(:account) do
|
1659
|
-
Account.new(name: "testing")
|
1660
|
-
end
|
1661
|
-
|
1662
|
-
context "when the document is not valid in the upsert context" do
|
1663
|
-
|
1664
|
-
before do
|
1665
|
-
account.upsert
|
1666
|
-
end
|
1667
|
-
|
1668
|
-
it "adds the validation errors" do
|
1669
|
-
account.errors[:nickname].should_not be_empty
|
1670
|
-
end
|
1671
|
-
|
1672
|
-
it "does not upsert the document" do
|
1673
|
-
account.should be_a_new_record
|
1674
|
-
end
|
1675
|
-
end
|
1676
|
-
end
|
1677
|
-
|
1678
|
-
context "when the document is new" do
|
1679
|
-
|
1680
|
-
let!(:existing) do
|
1681
|
-
Band.create(name: "Photek")
|
1682
|
-
end
|
1683
|
-
|
1684
|
-
context "when a matching document exists in the db" do
|
1685
|
-
|
1686
|
-
let(:updated) do
|
1687
|
-
Band.new(name: "Tool") do |band|
|
1688
|
-
band.id = existing.id
|
1689
|
-
end
|
1690
|
-
end
|
1691
|
-
|
1692
|
-
before do
|
1693
|
-
updated.with(safe: true).upsert
|
1694
|
-
end
|
1695
|
-
|
1696
|
-
it "updates the existing document" do
|
1697
|
-
existing.reload.name.should eq("Tool")
|
1698
|
-
end
|
1699
|
-
end
|
1700
|
-
|
1701
|
-
context "when no matching document exists in the db" do
|
1702
|
-
|
1703
|
-
let(:insert) do
|
1704
|
-
Band.new(name: "Tool")
|
1705
|
-
end
|
1706
|
-
|
1707
|
-
before do
|
1708
|
-
insert.with(safe: true).upsert
|
1709
|
-
end
|
1710
|
-
|
1711
|
-
it "inserts a new document" do
|
1712
|
-
insert.reload.should eq(insert)
|
1713
|
-
end
|
1714
|
-
|
1715
|
-
it "does not modify any fields" do
|
1716
|
-
insert.reload.name.should eq("Tool")
|
1717
|
-
end
|
1718
|
-
|
1719
|
-
it "sets the document as persisted" do
|
1720
|
-
insert.should be_persisted
|
1721
|
-
end
|
1722
|
-
end
|
1723
|
-
end
|
1724
|
-
|
1725
|
-
context "when the document is not new" do
|
1726
|
-
|
1727
|
-
let!(:existing) do
|
1728
|
-
Band.create(name: "Photek")
|
1729
|
-
end
|
1730
|
-
|
1731
|
-
context "when updating fields outside of the id" do
|
1732
|
-
|
1733
|
-
before do
|
1734
|
-
existing.name = "Depeche Mode"
|
1735
|
-
end
|
1736
|
-
|
1737
|
-
let!(:upsert) do
|
1738
|
-
existing.upsert
|
1739
|
-
end
|
1740
|
-
|
1741
|
-
it "updates the existing document" do
|
1742
|
-
existing.reload.name.should eq("Depeche Mode")
|
1743
|
-
end
|
1744
|
-
|
1745
|
-
it "returns true" do
|
1746
|
-
upsert.should be_true
|
1747
|
-
end
|
1748
|
-
end
|
1749
|
-
end
|
1750
|
-
end
|
1751
|
-
|
1752
|
-
[ :delete_all, :destroy_all ].each do |method|
|
1753
|
-
|
1754
|
-
describe "##{method}" do
|
1755
|
-
|
1756
|
-
let!(:person) do
|
1757
|
-
Person.create(title: "sir")
|
1758
|
-
end
|
1759
|
-
|
1760
|
-
context "when no conditions are provided" do
|
1761
|
-
|
1762
|
-
let!(:removed) do
|
1763
|
-
Person.send(method)
|
1764
|
-
end
|
1765
|
-
|
1766
|
-
it "removes all the documents" do
|
1767
|
-
Person.count.should eq(0)
|
1768
|
-
end
|
1769
|
-
|
1770
|
-
it "returns the number of documents removed" do
|
1771
|
-
removed.should eq(1)
|
1772
|
-
end
|
1773
|
-
end
|
1774
|
-
|
1775
|
-
context "when conditions are provided" do
|
1776
|
-
|
1777
|
-
let!(:person_two) do
|
1778
|
-
Person.create
|
1779
|
-
end
|
1780
|
-
|
1781
|
-
context "when in a conditions attribute" do
|
1782
|
-
|
1783
|
-
let!(:removed) do
|
1784
|
-
Person.send(method, conditions: { title: "sir" })
|
1785
|
-
end
|
1786
|
-
|
1787
|
-
it "removes the matching documents" do
|
1788
|
-
Person.count.should eq(1)
|
1789
|
-
end
|
1790
|
-
|
1791
|
-
it "returns the number of documents removed" do
|
1792
|
-
removed.should eq(1)
|
1793
|
-
end
|
1794
|
-
end
|
1795
|
-
|
1796
|
-
context "when no conditions attribute provided" do
|
1797
|
-
|
1798
|
-
let!(:removed) do
|
1799
|
-
Person.send(method, title: "sir")
|
1800
|
-
end
|
1801
|
-
|
1802
|
-
it "removes the matching documents" do
|
1803
|
-
Person.count.should eq(1)
|
1804
|
-
end
|
1805
|
-
|
1806
|
-
it "returns the number of documents removed" do
|
1807
|
-
removed.should eq(1)
|
1808
|
-
end
|
1809
|
-
end
|
1810
|
-
end
|
1811
|
-
end
|
1812
|
-
end
|
1813
|
-
|
1814
|
-
context "when a DateTime attribute is updated and persisted" do
|
1815
|
-
|
1816
|
-
let(:user) do
|
1817
|
-
User.create!(last_login: 2.days.ago).tap do |u|
|
1818
|
-
u.last_login = DateTime.now
|
1819
|
-
end
|
1820
|
-
end
|
1821
|
-
|
1822
|
-
it "reads for persistance as a UTC Time" do
|
1823
|
-
user.changes["last_login"].last.class.should eq(Time)
|
1824
|
-
end
|
1825
|
-
|
1826
|
-
it "persists with no exceptions thrown" do
|
1827
|
-
user.save!
|
1828
|
-
end
|
1829
|
-
end
|
1830
|
-
|
1831
|
-
context "when a Date attribute is persisted" do
|
1832
|
-
|
1833
|
-
let(:user) do
|
1834
|
-
User.create!(account_expires: 2.years.from_now).tap do |u|
|
1835
|
-
u.account_expires = "2/2/2002".to_date
|
1836
|
-
end
|
1837
|
-
end
|
1838
|
-
|
1839
|
-
it "reads for persistance as a UTC Time" do
|
1840
|
-
user.changes["account_expires"].last.class.should eq(Time)
|
1841
|
-
end
|
1842
|
-
|
1843
|
-
it "persists with no exceptions thrown" do
|
1844
|
-
user.save!
|
1845
|
-
end
|
1846
|
-
end
|
1847
|
-
|
1848
|
-
context "when setting floating point numbers" do
|
1849
|
-
|
1850
|
-
context "when value is an empty string" do
|
1851
|
-
|
1852
|
-
let(:person) do
|
1853
|
-
Person.new
|
1854
|
-
end
|
1855
|
-
|
1856
|
-
before do
|
1857
|
-
Person.validates_numericality_of :blood_alcohol_content, allow_blank: true
|
1858
|
-
end
|
1859
|
-
|
1860
|
-
it "does not set the value" do
|
1861
|
-
person.save.should be_true
|
1862
|
-
end
|
1863
|
-
end
|
1864
|
-
end
|
1865
|
-
|
1866
|
-
context "when setting association foreign keys" do
|
1867
|
-
|
1868
|
-
let(:game) do
|
1869
|
-
Game.new
|
1870
|
-
end
|
1871
|
-
|
1872
|
-
let(:person) do
|
1873
|
-
Person.create
|
1874
|
-
end
|
1875
|
-
|
1876
|
-
context "when value is an empty string" do
|
1877
|
-
|
1878
|
-
before do
|
1879
|
-
game.person_id = ""
|
1880
|
-
game.save
|
1881
|
-
end
|
1882
|
-
|
1883
|
-
it "sets the foreign key to empty" do
|
1884
|
-
game.reload.person_id.should be_blank
|
1885
|
-
end
|
1886
|
-
end
|
1887
|
-
|
1888
|
-
context "when value is a populated string" do
|
1889
|
-
|
1890
|
-
before do
|
1891
|
-
game.person_id = person.id.to_s
|
1892
|
-
game.save
|
1893
|
-
end
|
1894
|
-
|
1895
|
-
it "sets the foreign key as ObjectID" do
|
1896
|
-
game.reload.person_id.should eq(person.id)
|
1897
|
-
end
|
1898
|
-
end
|
1899
|
-
|
1900
|
-
context "when value is a ObjectID" do
|
1901
|
-
|
1902
|
-
before do
|
1903
|
-
game.person_id = person.id
|
1904
|
-
game.save
|
1905
|
-
end
|
1906
|
-
|
1907
|
-
it "keeps the the foreign key as ObjectID" do
|
1908
|
-
game.reload.person_id.should eq(person.id)
|
1909
|
-
end
|
1910
|
-
end
|
1911
|
-
end
|
1912
|
-
|
1913
|
-
context "when the document is a subclass of a root class" do
|
1914
|
-
|
1915
|
-
let!(:browser) do
|
1916
|
-
Browser.create(version: 3, name: "Test")
|
1917
|
-
end
|
1918
|
-
|
1919
|
-
let(:collection) do
|
1920
|
-
Canvas.collection
|
1921
|
-
end
|
1922
|
-
|
1923
|
-
let(:attributes) do
|
1924
|
-
collection.find({ name: "Test"}).first
|
1925
|
-
end
|
1926
|
-
|
1927
|
-
it "persists the versions" do
|
1928
|
-
attributes["version"].should eq(3)
|
1929
|
-
end
|
1930
|
-
|
1931
|
-
it "persists the type" do
|
1932
|
-
attributes["_type"].should eq("Browser")
|
1933
|
-
end
|
1934
|
-
|
1935
|
-
it "persists the attributes" do
|
1936
|
-
attributes["name"].should eq("Test")
|
1937
|
-
end
|
1938
|
-
end
|
1939
|
-
|
1940
|
-
context "when the document is a subclass of a subclass" do
|
1941
|
-
|
1942
|
-
let!(:firefox) do
|
1943
|
-
Firefox.create(version: 2, name: "Testy")
|
1944
|
-
end
|
1945
|
-
|
1946
|
-
let(:collection) do
|
1947
|
-
Canvas.collection
|
1948
|
-
end
|
1949
|
-
|
1950
|
-
let(:attributes) do
|
1951
|
-
collection.find({ name: "Testy"}).first
|
1952
|
-
end
|
1953
|
-
|
1954
|
-
before do
|
1955
|
-
Browser.create(name: 'Safari', version: '4.0.0')
|
1956
|
-
end
|
1957
|
-
|
1958
|
-
it "persists the versions" do
|
1959
|
-
attributes["version"].should eq(2)
|
1960
|
-
end
|
1961
|
-
|
1962
|
-
it "persists the type" do
|
1963
|
-
attributes["_type"].should eq("Firefox")
|
1964
|
-
end
|
1965
|
-
|
1966
|
-
it "persists the attributes" do
|
1967
|
-
attributes["name"].should eq("Testy")
|
1968
|
-
end
|
1969
|
-
|
1970
|
-
it "returns the document when querying for superclass" do
|
1971
|
-
Browser.where(name: "Testy").first.should eq(firefox)
|
1972
|
-
end
|
1973
|
-
|
1974
|
-
it "returns the document when querying for root class" do
|
1975
|
-
Canvas.where(name: "Testy").first.should eq(firefox)
|
1976
|
-
end
|
1977
|
-
|
1978
|
-
it 'returnss on of this subclasses if you find by _type' do
|
1979
|
-
Canvas.where(:_type.in => ['Firefox']).count.should eq(1)
|
1980
|
-
end
|
1981
|
-
end
|
1982
|
-
|
1983
|
-
context "when the document has associations" do
|
1984
|
-
|
1985
|
-
let!(:firefox) do
|
1986
|
-
Firefox.create(name: "firefox")
|
1987
|
-
end
|
1988
|
-
|
1989
|
-
let!(:writer) do
|
1990
|
-
HtmlWriter.new(speed: 100)
|
1991
|
-
end
|
1992
|
-
|
1993
|
-
let!(:circle) do
|
1994
|
-
Circle.new(radius: 50)
|
1995
|
-
end
|
1996
|
-
|
1997
|
-
let!(:square) do
|
1998
|
-
Square.new(width: 300, height: 150)
|
1999
|
-
end
|
2000
|
-
|
2001
|
-
let(:from_db) do
|
2002
|
-
Firefox.find(firefox.id)
|
2003
|
-
end
|
2004
|
-
|
2005
|
-
before do
|
2006
|
-
firefox.writer = writer
|
2007
|
-
firefox.shapes << [ circle, square ]
|
2008
|
-
firefox.save!
|
2009
|
-
end
|
2010
|
-
|
2011
|
-
it "properly persists the one-to-one type" do
|
2012
|
-
from_db.should be_a_kind_of(Firefox)
|
2013
|
-
end
|
2014
|
-
|
2015
|
-
it "properly persists the one-to-one relations" do
|
2016
|
-
from_db.writer.should eq(writer)
|
2017
|
-
end
|
2018
|
-
|
2019
|
-
it "properly persists the one-to-many type" do
|
2020
|
-
from_db.shapes.first.should eq(circle)
|
2021
|
-
end
|
2022
|
-
|
2023
|
-
it "properly persists the one-to-many relations" do
|
2024
|
-
from_db.shapes.last.should eq(square)
|
2025
|
-
end
|
2026
|
-
|
2027
|
-
it "properly sets up the parent relation" do
|
2028
|
-
from_db.shapes.first.should eq(circle)
|
2029
|
-
end
|
2030
|
-
|
2031
|
-
it "properly sets up the entire hierarchy" do
|
2032
|
-
from_db.shapes.first.canvas.should eq(firefox)
|
2033
|
-
end
|
2034
|
-
end
|
2035
|
-
|
2036
|
-
context "when the document is subclassed" do
|
2037
|
-
|
2038
|
-
let!(:firefox) do
|
2039
|
-
Firefox.create(name: "firefox")
|
2040
|
-
end
|
2041
|
-
|
2042
|
-
it "finds the document with String args" do
|
2043
|
-
Firefox.find(firefox.id.to_s).should eq(firefox)
|
2044
|
-
end
|
2045
|
-
|
2046
|
-
context "when querying for parent documents" do
|
2047
|
-
|
2048
|
-
let(:canvas) do
|
2049
|
-
Canvas.where(name: "firefox").first
|
2050
|
-
end
|
2051
|
-
|
2052
|
-
it "returns matching subclasses" do
|
2053
|
-
canvas.should eq(firefox)
|
2054
|
-
end
|
2055
|
-
end
|
2056
|
-
end
|
2057
|
-
|
2058
|
-
context "when deleting subclasses" do
|
2059
|
-
|
2060
|
-
let!(:firefox) do
|
2061
|
-
Firefox.create(name: "firefox")
|
2062
|
-
end
|
2063
|
-
|
2064
|
-
let!(:firefox2) do
|
2065
|
-
Firefox.create(name: "firefox 2")
|
2066
|
-
end
|
2067
|
-
|
2068
|
-
let!(:browser) do
|
2069
|
-
Browser.create(name: "browser")
|
2070
|
-
end
|
2071
|
-
|
2072
|
-
let!(:canvas) do
|
2073
|
-
Canvas.create(name: "canvas")
|
2074
|
-
end
|
2075
|
-
|
2076
|
-
context "when deleting a single document" do
|
2077
|
-
|
2078
|
-
before do
|
2079
|
-
firefox.delete
|
2080
|
-
end
|
2081
|
-
|
2082
|
-
it "deletes from the parent class collection" do
|
2083
|
-
Canvas.count.should eq(3)
|
2084
|
-
end
|
2085
|
-
|
2086
|
-
it "returns correct counts for child classes" do
|
2087
|
-
Firefox.count.should eq(1)
|
2088
|
-
end
|
2089
|
-
|
2090
|
-
it "returns correct counts for root subclasses" do
|
2091
|
-
Browser.count.should eq(2)
|
2092
|
-
end
|
2093
|
-
end
|
2094
|
-
|
2095
|
-
context "when deleting all documents" do
|
2096
|
-
|
2097
|
-
before do
|
2098
|
-
Firefox.delete_all
|
2099
|
-
end
|
2100
|
-
|
2101
|
-
it "deletes from the parent class collection" do
|
2102
|
-
Canvas.count.should eq(2)
|
2103
|
-
end
|
2104
|
-
|
2105
|
-
it "returns correct counts for child classes" do
|
2106
|
-
Firefox.count.should eq(0)
|
2107
|
-
end
|
2108
|
-
|
2109
|
-
it "returns correct counts for root subclasses" do
|
2110
|
-
Browser.count.should eq(1)
|
2111
|
-
end
|
2112
|
-
end
|
2113
|
-
end
|
2114
|
-
|
2115
|
-
context "when document is a subclass and its parent is an embedded document" do
|
2116
|
-
|
2117
|
-
let!(:canvas) do
|
2118
|
-
Canvas.create(name: "canvas")
|
2119
|
-
end
|
2120
|
-
|
2121
|
-
before do
|
2122
|
-
canvas.create_palette
|
2123
|
-
canvas.palette.tools << Pencil.new
|
2124
|
-
canvas.palette.tools << Eraser.new
|
2125
|
-
end
|
2126
|
-
|
2127
|
-
let(:from_db) do
|
2128
|
-
Canvas.find(canvas.id)
|
2129
|
-
end
|
2130
|
-
|
2131
|
-
it "properly saves the subclasses" do
|
2132
|
-
from_db.palette.tools.map(&:class).should eq([Pencil, Eraser])
|
2133
|
-
end
|
2134
|
-
end
|
2135
|
-
|
2136
|
-
context "Creating references_many documents from a parent association" do
|
2137
|
-
|
2138
|
-
let!(:container) do
|
2139
|
-
ShippingContainer.create
|
2140
|
-
end
|
2141
|
-
|
2142
|
-
let(:driver) do
|
2143
|
-
Driver.create
|
2144
|
-
end
|
2145
|
-
|
2146
|
-
it "does not bleed relations from one subclass to another" do
|
2147
|
-
Truck.relations.keys.should =~ %w/ shipping_container driver bed /
|
2148
|
-
Car.relations.keys.should =~ %w/ shipping_container driver /
|
2149
|
-
end
|
2150
|
-
|
2151
|
-
context "when appending new documents" do
|
2152
|
-
|
2153
|
-
before do
|
2154
|
-
container.vehicles << Car.new
|
2155
|
-
container.vehicles << Truck.new
|
2156
|
-
end
|
2157
|
-
|
2158
|
-
it "allows STI from << using model.new" do
|
2159
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2160
|
-
end
|
2161
|
-
end
|
2162
|
-
|
2163
|
-
context "when appending persisted documents" do
|
2164
|
-
|
2165
|
-
before do
|
2166
|
-
container.vehicles << Car.create
|
2167
|
-
container.vehicles << Truck.create
|
2168
|
-
end
|
2169
|
-
|
2170
|
-
it "allows STI from << using model.create" do
|
2171
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2172
|
-
end
|
2173
|
-
end
|
2174
|
-
|
2175
|
-
context "when building related documents" do
|
2176
|
-
|
2177
|
-
before do
|
2178
|
-
container.vehicles.build({}, Car).save
|
2179
|
-
container.vehicles.build({}, Truck).save
|
2180
|
-
end
|
2181
|
-
|
2182
|
-
it "allows STI from the build call" do
|
2183
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2184
|
-
end
|
2185
|
-
end
|
2186
|
-
|
2187
|
-
context "when building with a type attribute" do
|
2188
|
-
|
2189
|
-
before do
|
2190
|
-
container.vehicles.build({ "_type" => "Car" })
|
2191
|
-
container.vehicles.build({ "_type" => "Truck" })
|
2192
|
-
end
|
2193
|
-
|
2194
|
-
it "respects the _type attribute from the build call" do
|
2195
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2196
|
-
end
|
2197
|
-
end
|
2198
|
-
|
2199
|
-
context "when creating related documents" do
|
2200
|
-
|
2201
|
-
before do
|
2202
|
-
container.vehicles.create({}, Car)
|
2203
|
-
container.vehicles.create({}, Truck)
|
2204
|
-
end
|
2205
|
-
|
2206
|
-
it "allows STI from the create call" do
|
2207
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2208
|
-
end
|
2209
|
-
end
|
2210
|
-
|
2211
|
-
context "when creating with a type attribute" do
|
2212
|
-
|
2213
|
-
before do
|
2214
|
-
container.vehicles.create({ "_type" => "Car" })
|
2215
|
-
container.vehicles.create({ "_type" => "Truck" })
|
2216
|
-
end
|
2217
|
-
|
2218
|
-
it "respects the _type attribute from the create call" do
|
2219
|
-
container.vehicles.map(&:class).should eq([ Car, Truck ])
|
2220
|
-
end
|
2221
|
-
end
|
2222
|
-
|
2223
|
-
context "#find_or_initialize_by" do
|
2224
|
-
|
2225
|
-
before do
|
2226
|
-
container.vehicles.find_or_initialize_by({ driver_id: driver.id }, Car)
|
2227
|
-
end
|
2228
|
-
|
2229
|
-
it "initializes the given type document" do
|
2230
|
-
container.vehicles.map(&:class).should eq([ Car ])
|
2231
|
-
end
|
2232
|
-
|
2233
|
-
it "initializes with the given attributes" do
|
2234
|
-
container.vehicles.map(&:driver).should eq([ driver ])
|
2235
|
-
end
|
2236
|
-
end
|
2237
|
-
|
2238
|
-
context "#find_or_create_by" do
|
2239
|
-
|
2240
|
-
before do
|
2241
|
-
container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
|
2242
|
-
end
|
2243
|
-
|
2244
|
-
it "creates the given type document" do
|
2245
|
-
container.vehicles.map(&:class).should eq([ Car ])
|
2246
|
-
end
|
2247
|
-
|
2248
|
-
it "creates with the given attributes" do
|
2249
|
-
container.vehicles.map(&:driver).should eq([ driver ])
|
2250
|
-
end
|
2251
|
-
|
2252
|
-
it "creates the correct number of documents" do
|
2253
|
-
container.vehicles.size.should eq(1)
|
2254
|
-
end
|
2255
|
-
|
2256
|
-
context "when executing with a found document" do
|
2257
|
-
|
2258
|
-
before do
|
2259
|
-
container.vehicles.find_or_create_by({ driver_id: driver.id }, Car)
|
2260
|
-
end
|
2261
|
-
|
2262
|
-
it "does not create an additional document" do
|
2263
|
-
container.vehicles.size.should eq(1)
|
2264
|
-
end
|
2265
|
-
end
|
2266
|
-
|
2267
|
-
context "when executing with an additional new document" do
|
2268
|
-
|
2269
|
-
before do
|
2270
|
-
container.vehicles.find_or_create_by({ driver_id: driver.id }, Truck)
|
2271
|
-
end
|
2272
|
-
|
2273
|
-
it "creates the new additional document" do
|
2274
|
-
container.vehicles.size.should eq(2)
|
2275
|
-
end
|
2276
|
-
end
|
2277
|
-
end
|
2278
|
-
end
|
2279
|
-
end
|