mongoid 3.1.6 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +432 -8
- data/README.md +5 -6
- data/lib/config/locales/en.yml +32 -18
- 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/embedded.rb +0 -30
- data/lib/mongoid/atomic/paths/root.rb +0 -13
- data/lib/mongoid/atomic.rb +1 -12
- 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/attributes.rb +63 -101
- data/lib/mongoid/{dirty.rb → changeable.rb} +32 -2
- data/lib/mongoid/composable.rb +105 -0
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config.rb +3 -9
- 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 +18 -6
- data/lib/mongoid/contextual/mongo.rb +64 -56
- data/lib/mongoid/contextual/none.rb +90 -0
- data/lib/mongoid/contextual/text_search.rb +178 -0
- data/lib/mongoid/contextual.rb +2 -0
- data/lib/mongoid/copyable.rb +2 -3
- 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/criteria.rb +39 -34
- data/lib/mongoid/document.rb +32 -17
- 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/errors.rb +4 -1
- 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/extensions.rb +2 -7
- data/lib/mongoid/factory.rb +8 -6
- 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/fields.rb +41 -8
- data/lib/mongoid/{finders.rb → findable.rb} +8 -2
- data/lib/mongoid/indexable/specification.rb +104 -0
- data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
- data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
- 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/{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/matchable.rb +152 -0
- data/lib/mongoid/persistable/creatable.rb +188 -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 +152 -0
- data/lib/mongoid/persistable/upsertable.rb +55 -0
- data/lib/mongoid/persistable.rb +216 -0
- data/lib/mongoid/positional.rb +71 -0
- data/lib/mongoid/query_cache.rb +247 -0
- data/lib/mongoid/railtie.rb +32 -45
- data/lib/mongoid/railties/database.rake +9 -25
- data/lib/mongoid/relations/accessors.rb +13 -49
- data/lib/mongoid/relations/auto_save.rb +15 -36
- data/lib/mongoid/relations/binding.rb +1 -24
- 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 +3 -1
- data/lib/mongoid/relations/builder.rb +1 -1
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +10 -13
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +4 -5
- 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/builders.rb +2 -2
- 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/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/eager.rb +46 -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 +30 -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/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 +19 -32
- data/lib/mongoid/relations/referenced/many_to_many.rb +15 -38
- data/lib/mongoid/relations/referenced/one.rb +6 -25
- data/lib/mongoid/relations/synchronization.rb +3 -3
- data/lib/mongoid/relations/touchable.rb +34 -1
- data/lib/mongoid/relations.rb +11 -25
- data/lib/mongoid/{reloading.rb → reloadable.rb} +6 -4
- 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/factory.rb +2 -0
- data/lib/mongoid/sessions/options.rb +180 -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/sessions.rb +37 -345
- 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/lifecycle.rb +0 -28
- data/lib/mongoid/threaded.rb +0 -157
- data/lib/mongoid/timestamps/updated/short.rb +2 -2
- data/lib/mongoid/{hierarchy.rb → traversable.rb} +9 -5
- 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 +23 -19
- data/lib/mongoid/{validations.rb → validatable.rb} +23 -10
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +10 -76
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +13 -24
- 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/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/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/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} +335 -448
- data/spec/mongoid/attributes/readonly_spec.rb +58 -18
- data/spec/mongoid/attributes_spec.rb +315 -436
- 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 +68 -58
- 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 +151 -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 +1255 -0
- data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +37 -37
- data/spec/mongoid/criteria_spec.rb +578 -2295
- data/spec/mongoid/document_spec.rb +166 -120
- 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 +15 -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/{finders_spec.rb → findable_spec.rb} +127 -27
- 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 +512 -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 +461 -0
- data/spec/mongoid/persistable/settable_spec.rb +139 -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} +9 -9
- data/spec/mongoid/query_cache_spec.rb +231 -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 +393 -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 +434 -527
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +352 -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} +20 -60
- 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 +107 -0
- data/spec/mongoid/sessions_spec.rb +289 -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 +29 -13
- metadata +296 -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/strategies.rb +0 -97
- data/lib/mongoid/matchers.rb +0 -32
- 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/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/atomic.rb +0 -231
- 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/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/operations.rb +0 -214
- data/lib/mongoid/persistence/upsertion.rb +0 -31
- data/lib/mongoid/persistence.rb +0 -357
- data/lib/mongoid/unit_of_work.rb +0 -61
- data/lib/mongoid/versioning.rb +0 -217
- data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
- data/lib/rack/mongoid.rb +0 -2
- 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/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
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for $pull and $pullAll operations.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Pullable
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Pull single values from the provided arrays.
|
|
12
|
+
#
|
|
13
|
+
# @example Pull a value from the array.
|
|
14
|
+
# document.pull(names: "Jeff", levels: 5)
|
|
15
|
+
#
|
|
16
|
+
# @note If duplicate values are found they will all be pulled.
|
|
17
|
+
#
|
|
18
|
+
# @param [ Hash ] pulls The field/value pull pairs.
|
|
19
|
+
#
|
|
20
|
+
# @return [ true, false ] If the operation succeeded.
|
|
21
|
+
#
|
|
22
|
+
# @since 4.0.0
|
|
23
|
+
def pull(pulls)
|
|
24
|
+
prepare_atomic_operation do |ops|
|
|
25
|
+
process_atomic_operations(pulls) do |field, value|
|
|
26
|
+
(send(field) || []).delete(value)
|
|
27
|
+
ops[atomic_attribute_name(field)] = value
|
|
28
|
+
end
|
|
29
|
+
{ "$pull" => ops }
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Pull multiple values from the provided array fields.
|
|
34
|
+
#
|
|
35
|
+
# @example Pull values from the arrays.
|
|
36
|
+
# document.pull_all(names: [ "Jeff", "Bob" ], levels: [ 5, 6 ])
|
|
37
|
+
#
|
|
38
|
+
# @param [ Hash ] pulls The pull all operations.
|
|
39
|
+
#
|
|
40
|
+
# @return [ true, false ] If the operation succeeded.
|
|
41
|
+
#
|
|
42
|
+
# @since 4.0.0
|
|
43
|
+
def pull_all(pulls)
|
|
44
|
+
prepare_atomic_operation do |ops|
|
|
45
|
+
process_atomic_operations(pulls) do |field, value|
|
|
46
|
+
existing = send(field) || []
|
|
47
|
+
value.each{ |val| existing.delete(val) }
|
|
48
|
+
ops[atomic_attribute_name(field)] = value
|
|
49
|
+
end
|
|
50
|
+
{ "$pullAll" => ops }
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for $push and $addToSet operations.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Pushable
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Add the single values to the arrays only if the value does not already
|
|
12
|
+
# exist in the array.
|
|
13
|
+
#
|
|
14
|
+
# @example Add the values to the sets.
|
|
15
|
+
# document.add_to_set(names: "James", aliases: "Bond")
|
|
16
|
+
#
|
|
17
|
+
# @param [ Hash ] adds The field/value pairs to add.
|
|
18
|
+
#
|
|
19
|
+
# @return [ true, false ] If the operation succeeded.
|
|
20
|
+
#
|
|
21
|
+
# @since 4.0.0
|
|
22
|
+
def add_to_set(adds)
|
|
23
|
+
prepare_atomic_operation do |ops|
|
|
24
|
+
process_atomic_operations(adds) do |field, value|
|
|
25
|
+
existing = send(field) || (attributes[field] ||= [])
|
|
26
|
+
values = [ value ].flatten(1)
|
|
27
|
+
values.each do |val|
|
|
28
|
+
existing.push(val) unless existing.include?(val)
|
|
29
|
+
end
|
|
30
|
+
ops[atomic_attribute_name(field)] = { "$each" => values }
|
|
31
|
+
end
|
|
32
|
+
{ "$addToSet" => ops }
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Push a single value or multiple values onto arrays.
|
|
37
|
+
#
|
|
38
|
+
# @example Push a single value onto arrays.
|
|
39
|
+
# document.push(names: "James", aliases: "007")
|
|
40
|
+
#
|
|
41
|
+
# @example Push multiple values onto arrays.
|
|
42
|
+
# document.push(names: [ "James", "Bond" ])
|
|
43
|
+
#
|
|
44
|
+
# @param [ Hash ] pushes The $push operations.
|
|
45
|
+
#
|
|
46
|
+
# @return [ true, false ] If the operation succeeded.
|
|
47
|
+
#
|
|
48
|
+
# @since 4.0.0
|
|
49
|
+
def push(pushes)
|
|
50
|
+
prepare_atomic_operation do |ops|
|
|
51
|
+
process_atomic_operations(pushes) do |field, value|
|
|
52
|
+
existing = send(field) || (attributes[field] ||= [])
|
|
53
|
+
values = [ value ].flatten(1)
|
|
54
|
+
values.each{ |val| existing.push(val) }
|
|
55
|
+
ops[atomic_attribute_name(field)] = { "$each" => values }
|
|
56
|
+
end
|
|
57
|
+
{ "$push" => ops }
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for $rename operations.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Renamable
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Rename fields from one value to another via $rename.
|
|
12
|
+
#
|
|
13
|
+
# @example Rename the fields.
|
|
14
|
+
# document.rename(title: "salutation", name: "nombre")
|
|
15
|
+
#
|
|
16
|
+
# @note This does not work for fields in embeds many relations.
|
|
17
|
+
#
|
|
18
|
+
# @param [ Hash ] renames The rename pairs of old name/new name.
|
|
19
|
+
#
|
|
20
|
+
# @return [ true, false ] If the rename suceeded.
|
|
21
|
+
#
|
|
22
|
+
# @since 4.0.0
|
|
23
|
+
def rename(renames)
|
|
24
|
+
prepare_atomic_operation do |ops|
|
|
25
|
+
process_atomic_operations(renames) do |old_field, new_field|
|
|
26
|
+
new_name = new_field.to_s
|
|
27
|
+
attributes[new_name] = attributes.delete(old_field)
|
|
28
|
+
ops[atomic_attribute_name(old_field)] = atomic_attribute_name(new_name)
|
|
29
|
+
end
|
|
30
|
+
{ "$rename" => ops }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for persistence operations that save documents.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Savable
|
|
9
|
+
|
|
10
|
+
# Save the document - will perform an insert if the document is new, and
|
|
11
|
+
# update if not.
|
|
12
|
+
#
|
|
13
|
+
# @example Save the document.
|
|
14
|
+
# document.save
|
|
15
|
+
#
|
|
16
|
+
# @param [ Hash ] options Options to pass to the save.
|
|
17
|
+
#
|
|
18
|
+
# @return [ true, false ] True is success, false if not.
|
|
19
|
+
#
|
|
20
|
+
# @since 1.0.0
|
|
21
|
+
def save(options = {})
|
|
22
|
+
if new_record?
|
|
23
|
+
!insert(options).new_record?
|
|
24
|
+
else
|
|
25
|
+
update_document(options)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Save the document - will perform an insert if the document is new, and
|
|
30
|
+
# update if not. If a validation error occurs an error will get raised.
|
|
31
|
+
#
|
|
32
|
+
# @example Save the document.
|
|
33
|
+
# document.save!
|
|
34
|
+
#
|
|
35
|
+
# @param [ Hash ] options Options to pass to the save.
|
|
36
|
+
#
|
|
37
|
+
# @raise [ Errors::Validations ] If validation failed.
|
|
38
|
+
# @raise [ Errors::Callback ] If a callback returns false.
|
|
39
|
+
#
|
|
40
|
+
# @return [ true, false ] True if validation passed.
|
|
41
|
+
#
|
|
42
|
+
# @since 1.0.0
|
|
43
|
+
def save!(options = {})
|
|
44
|
+
unless save(options)
|
|
45
|
+
fail_due_to_validation! unless errors.empty?
|
|
46
|
+
fail_due_to_callback!(:save!)
|
|
47
|
+
end
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for $set operations.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Settable
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Perform a $set operation on the provided field/value pairs and set the
|
|
12
|
+
# values in the document in memory.
|
|
13
|
+
#
|
|
14
|
+
# @example Set the values.
|
|
15
|
+
# document.set(title: "sir", dob: Date.new(1970, 1, 1))
|
|
16
|
+
#
|
|
17
|
+
# @param [ Hash ] setters The field/value pairs to set.
|
|
18
|
+
#
|
|
19
|
+
# @return [ true ] If the operation succeeded.
|
|
20
|
+
#
|
|
21
|
+
# @since 4.0.0
|
|
22
|
+
def set(setters)
|
|
23
|
+
prepare_atomic_operation do |ops|
|
|
24
|
+
process_atomic_operations(setters) do |field, value|
|
|
25
|
+
send("#{field}=", value)
|
|
26
|
+
ops[atomic_attribute_name(field)] = attributes[field]
|
|
27
|
+
end
|
|
28
|
+
{ "$set" => ops }
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for $unset operations.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Unsettable
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Perform an $unset operation on the provided fields and in the
|
|
12
|
+
# values in the document in memory.
|
|
13
|
+
#
|
|
14
|
+
# @example Unset the values.
|
|
15
|
+
# document.unset(:first_name, :last_name, :middle)
|
|
16
|
+
#
|
|
17
|
+
# @param [ Array<String, Symbol> ] fields The names of the fields to
|
|
18
|
+
# unset.
|
|
19
|
+
#
|
|
20
|
+
# @return [ true ] If the operation succeeded.
|
|
21
|
+
#
|
|
22
|
+
# @since 4.0.0
|
|
23
|
+
def unset(*fields)
|
|
24
|
+
prepare_atomic_operation do |ops|
|
|
25
|
+
fields.flatten.each do |field|
|
|
26
|
+
normalized = database_field_name(field)
|
|
27
|
+
attributes.delete(normalized)
|
|
28
|
+
ops[atomic_attribute_name(normalized)] = true
|
|
29
|
+
end
|
|
30
|
+
{ "$unset" => ops }
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for persistence operations that update existing
|
|
6
|
+
# documents.
|
|
7
|
+
#
|
|
8
|
+
# @since 4.0.0
|
|
9
|
+
module Updatable
|
|
10
|
+
|
|
11
|
+
# Update a single attribute and persist the entire document.
|
|
12
|
+
# This skips validation but fires the callbacks.
|
|
13
|
+
#
|
|
14
|
+
# @example Update the attribute.
|
|
15
|
+
# person.update_attribute(:title, "Sir")
|
|
16
|
+
#
|
|
17
|
+
# @param [ Symbol, String ] name The name of the attribute.
|
|
18
|
+
# @param [ Object ] value The new value of the attribute.a
|
|
19
|
+
#
|
|
20
|
+
# @raise [ Errors::ReadonlyAttribute ] If the field cannot be changed due
|
|
21
|
+
# to being flagged as reaodnly.
|
|
22
|
+
#
|
|
23
|
+
# @return [ true, false ] True if save was successfull, false if not.
|
|
24
|
+
#
|
|
25
|
+
# @since 2.0.0
|
|
26
|
+
def update_attribute(name, value)
|
|
27
|
+
normalized = name.to_s
|
|
28
|
+
unless attribute_writable?(normalized)
|
|
29
|
+
raise Errors::ReadonlyAttribute.new(normalized, value)
|
|
30
|
+
end
|
|
31
|
+
setter = "#{normalized}="
|
|
32
|
+
if respond_to?(setter)
|
|
33
|
+
send(setter, value)
|
|
34
|
+
else
|
|
35
|
+
write_attribute(database_field_name(normalized), value)
|
|
36
|
+
end
|
|
37
|
+
save(validate: false)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Update the document attributes in the database.
|
|
41
|
+
#
|
|
42
|
+
# @example Update the document's attributes
|
|
43
|
+
# document.update(:title => "Sir")
|
|
44
|
+
#
|
|
45
|
+
# @param [ Hash ] attributes The attributes to update.
|
|
46
|
+
#
|
|
47
|
+
# @return [ true, false ] True if validation passed, false if not.
|
|
48
|
+
#
|
|
49
|
+
# @since 1.0.0
|
|
50
|
+
def update(attributes = {})
|
|
51
|
+
assign_attributes(attributes)
|
|
52
|
+
save
|
|
53
|
+
end
|
|
54
|
+
alias :update_attributes :update
|
|
55
|
+
|
|
56
|
+
# Update the document attributes in the database and raise an error if
|
|
57
|
+
# validation failed.
|
|
58
|
+
#
|
|
59
|
+
# @example Update the document's attributes.
|
|
60
|
+
# document.update!(:title => "Sir")
|
|
61
|
+
#
|
|
62
|
+
# @param [ Hash ] attributes The attributes to update.
|
|
63
|
+
#
|
|
64
|
+
# @raise [ Errors::Validations ] If validation failed.
|
|
65
|
+
# @raise [ Errors::Callbacks ] If a callback returns false.
|
|
66
|
+
#
|
|
67
|
+
# @return [ true, false ] True if validation passed.
|
|
68
|
+
#
|
|
69
|
+
# @since 1.0.0
|
|
70
|
+
def update!(attributes = {})
|
|
71
|
+
result = update_attributes(attributes)
|
|
72
|
+
unless result
|
|
73
|
+
fail_due_to_validation! unless errors.empty?
|
|
74
|
+
fail_due_to_callback!(:update_attributes!)
|
|
75
|
+
end
|
|
76
|
+
result
|
|
77
|
+
end
|
|
78
|
+
alias :update_attributes! :update!
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# Initialize the atomic updates.
|
|
83
|
+
#
|
|
84
|
+
# @api private
|
|
85
|
+
#
|
|
86
|
+
# @example Initialize the atomic updates.
|
|
87
|
+
# document.init_atomic_updates
|
|
88
|
+
#
|
|
89
|
+
# @return [ Array<Hash> ] The updates and conflicts.
|
|
90
|
+
#
|
|
91
|
+
# @since 4.0.0
|
|
92
|
+
def init_atomic_updates
|
|
93
|
+
updates = atomic_updates
|
|
94
|
+
conflicts = updates.delete(:conflicts) || {}
|
|
95
|
+
[ updates, conflicts ]
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Prepare the update for execution. Validates and runs callbacks, etc.
|
|
99
|
+
#
|
|
100
|
+
# @api private
|
|
101
|
+
#
|
|
102
|
+
# @example Prepare for update.
|
|
103
|
+
# document.prepare_update do
|
|
104
|
+
# collection.update(atomic_selector)
|
|
105
|
+
# end
|
|
106
|
+
#
|
|
107
|
+
# @param [ Hash ] options The options.
|
|
108
|
+
#
|
|
109
|
+
# @return [ true, false ] The result of the update.
|
|
110
|
+
#
|
|
111
|
+
# @since 4.0.0
|
|
112
|
+
def prepare_update(options = {})
|
|
113
|
+
return false if performing_validations?(options) && invalid?(:update)
|
|
114
|
+
process_flagged_destroys
|
|
115
|
+
result = run_callbacks(:save) do
|
|
116
|
+
run_callbacks(:update) do
|
|
117
|
+
yield(self)
|
|
118
|
+
true
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
post_process_persist(result, options) and result
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Update the document in the database.
|
|
125
|
+
#
|
|
126
|
+
# @example Update an existing document.
|
|
127
|
+
# document.update
|
|
128
|
+
#
|
|
129
|
+
# @param [ Hash ] options Options to pass to update.
|
|
130
|
+
#
|
|
131
|
+
# @option options [ true, false ] :validate Whether or not to validate.
|
|
132
|
+
#
|
|
133
|
+
# @return [ true, false ] True if succeeded, false if not.
|
|
134
|
+
#
|
|
135
|
+
# @since 1.0.0
|
|
136
|
+
def update_document(options = {})
|
|
137
|
+
raise Errors::ReadonlyDocument.new(self.class) if readonly?
|
|
138
|
+
prepare_update(options) do
|
|
139
|
+
updates, conflicts = init_atomic_updates
|
|
140
|
+
unless updates.empty?
|
|
141
|
+
coll = _root.collection
|
|
142
|
+
selector = atomic_selector
|
|
143
|
+
coll.find(selector).update(positionally(selector, updates))
|
|
144
|
+
conflicts.each_pair do |key, value|
|
|
145
|
+
coll.find(selector).update(positionally(selector, { key => value }))
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Persistable
|
|
4
|
+
|
|
5
|
+
# Defines behaviour for persistence operations that upsert documents.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Upsertable
|
|
9
|
+
|
|
10
|
+
# Perform an upsert of the document. If the document does not exist in the
|
|
11
|
+
# database, then Mongo will insert a new one, otherwise the fields will get
|
|
12
|
+
# overwritten with new values on the existing document.
|
|
13
|
+
#
|
|
14
|
+
# @example Upsert the document.
|
|
15
|
+
# document.upsert
|
|
16
|
+
#
|
|
17
|
+
# @param [ Hash ] options The validation options.
|
|
18
|
+
#
|
|
19
|
+
# @return [ true ] True.
|
|
20
|
+
#
|
|
21
|
+
# @since 3.0.0
|
|
22
|
+
def upsert(options = {})
|
|
23
|
+
prepare_upsert(options) do
|
|
24
|
+
collection.find(atomic_selector).update(as_document, [ :upsert ])
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
# Prepare the upsert for execution.
|
|
31
|
+
#
|
|
32
|
+
# @api private
|
|
33
|
+
#
|
|
34
|
+
# @example Prepare the upsert
|
|
35
|
+
# document.prepare_upsert do
|
|
36
|
+
# collection.find(selector).update(as_document)
|
|
37
|
+
# end
|
|
38
|
+
#
|
|
39
|
+
# @param [ Hash ] options The options hash.
|
|
40
|
+
#
|
|
41
|
+
# @return [ true, false ] If the operation succeeded.
|
|
42
|
+
#
|
|
43
|
+
# @since 4.0.0
|
|
44
|
+
def prepare_upsert(options = {})
|
|
45
|
+
return false if performing_validations?(options) && invalid?(:upsert)
|
|
46
|
+
result = run_callbacks(:upsert) do
|
|
47
|
+
yield(self)
|
|
48
|
+
true
|
|
49
|
+
end
|
|
50
|
+
self.new_record = false
|
|
51
|
+
post_process_persist(result, options) and result
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
require "mongoid/persistable/creatable"
|
|
3
|
+
require "mongoid/persistable/deletable"
|
|
4
|
+
require "mongoid/persistable/destroyable"
|
|
5
|
+
require "mongoid/persistable/incrementable"
|
|
6
|
+
require "mongoid/persistable/logical"
|
|
7
|
+
require "mongoid/persistable/poppable"
|
|
8
|
+
require "mongoid/persistable/pullable"
|
|
9
|
+
require "mongoid/persistable/pushable"
|
|
10
|
+
require "mongoid/persistable/renamable"
|
|
11
|
+
require "mongoid/persistable/savable"
|
|
12
|
+
require "mongoid/persistable/settable"
|
|
13
|
+
require "mongoid/persistable/updatable"
|
|
14
|
+
require "mongoid/persistable/upsertable"
|
|
15
|
+
require "mongoid/persistable/unsettable"
|
|
16
|
+
|
|
17
|
+
module Mongoid
|
|
18
|
+
|
|
19
|
+
# Contains general behaviour for persistence operations.
|
|
20
|
+
#
|
|
21
|
+
# @since 2.0.0
|
|
22
|
+
module Persistable
|
|
23
|
+
extend ActiveSupport::Concern
|
|
24
|
+
include Creatable
|
|
25
|
+
include Deletable
|
|
26
|
+
include Destroyable
|
|
27
|
+
include Incrementable
|
|
28
|
+
include Logical
|
|
29
|
+
include Poppable
|
|
30
|
+
include Positional
|
|
31
|
+
include Pullable
|
|
32
|
+
include Pushable
|
|
33
|
+
include Renamable
|
|
34
|
+
include Savable
|
|
35
|
+
include Settable
|
|
36
|
+
include Updatable
|
|
37
|
+
include Upsertable
|
|
38
|
+
include Unsettable
|
|
39
|
+
|
|
40
|
+
# The atomic operations that deal with arrays or sets in the db.
|
|
41
|
+
#
|
|
42
|
+
# @since 4.0.0
|
|
43
|
+
LIST_OPERATIONS = [ "$addToSet", "$push", "$pull", "$pullAll" ].freeze
|
|
44
|
+
|
|
45
|
+
# Execute operations atomically (in a single database call) for everything
|
|
46
|
+
# that would happen inside the block.
|
|
47
|
+
#
|
|
48
|
+
# @example Execute the operations atomically.
|
|
49
|
+
# document.atomically do
|
|
50
|
+
# document.set(name: "Tool").inc(likes: 10)
|
|
51
|
+
# end
|
|
52
|
+
#
|
|
53
|
+
# @return [ true, false ] If the operation succeeded.
|
|
54
|
+
#
|
|
55
|
+
# @since 4.0.0
|
|
56
|
+
def atomically
|
|
57
|
+
begin
|
|
58
|
+
@atomic_updates_to_execute = {}
|
|
59
|
+
yield(self) if block_given?
|
|
60
|
+
persist_atomic_operations(@atomic_updates_to_execute)
|
|
61
|
+
true
|
|
62
|
+
ensure
|
|
63
|
+
@atomic_updates_to_execute = nil
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Raise an error if validation failed.
|
|
68
|
+
#
|
|
69
|
+
# @example Raise the validation error.
|
|
70
|
+
# Person.fail_due_to_validation!(person)
|
|
71
|
+
#
|
|
72
|
+
# @param [ Document ] document The document to fail.
|
|
73
|
+
#
|
|
74
|
+
# @raise [ Errors::Validations ] The validation error.
|
|
75
|
+
#
|
|
76
|
+
# @since 4.0.0
|
|
77
|
+
def fail_due_to_validation!
|
|
78
|
+
raise Errors::Validations.new(self)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Raise an error if a callback failed.
|
|
82
|
+
#
|
|
83
|
+
# @example Raise the callback error.
|
|
84
|
+
# Person.fail_due_to_callback!(person, :create!)
|
|
85
|
+
#
|
|
86
|
+
# @param [ Document ] document The document to fail.
|
|
87
|
+
# @param [ Symbol ] method The method being called.
|
|
88
|
+
#
|
|
89
|
+
# @raise [ Errors::Callback ] The callback error.
|
|
90
|
+
#
|
|
91
|
+
# @since 4.0.0
|
|
92
|
+
def fail_due_to_callback!(method)
|
|
93
|
+
raise Errors::Callback.new(self.class, method)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
private
|
|
97
|
+
|
|
98
|
+
# Are we executing an atomically block on the current document?
|
|
99
|
+
#
|
|
100
|
+
# @api private
|
|
101
|
+
#
|
|
102
|
+
# @example Are we executing atomically?
|
|
103
|
+
# document.executing_atomically?
|
|
104
|
+
#
|
|
105
|
+
# @return [ true, false ] If we are current executing atomically.
|
|
106
|
+
#
|
|
107
|
+
# @since 4.0.0
|
|
108
|
+
def executing_atomically?
|
|
109
|
+
!@atomic_updates_to_execute.nil?
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Post process the persistence operation.
|
|
113
|
+
#
|
|
114
|
+
# @api private
|
|
115
|
+
#
|
|
116
|
+
# @example Post process the persistence operation.
|
|
117
|
+
# document.post_process_persist(true)
|
|
118
|
+
#
|
|
119
|
+
# @param [ Object ] result The result of the operation.
|
|
120
|
+
# @param [ Hash ] options The options.
|
|
121
|
+
#
|
|
122
|
+
# @return [ true ] true.
|
|
123
|
+
#
|
|
124
|
+
# @since 4.0.0
|
|
125
|
+
def post_process_persist(result, options = {})
|
|
126
|
+
post_persist unless result == false
|
|
127
|
+
errors.clear unless performing_validations?(options)
|
|
128
|
+
true
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Prepare an atomic persistence operation. Yields an empty hash to be sent
|
|
132
|
+
# to the update.
|
|
133
|
+
#
|
|
134
|
+
# @api private
|
|
135
|
+
#
|
|
136
|
+
# @example Prepare the atomic operation.
|
|
137
|
+
# document.prepare_atomic_operation do |coll, selector, opts|
|
|
138
|
+
# ...
|
|
139
|
+
# end
|
|
140
|
+
#
|
|
141
|
+
# @return [ Object ] The result of the operation.
|
|
142
|
+
#
|
|
143
|
+
# @since 4.0.0
|
|
144
|
+
def prepare_atomic_operation
|
|
145
|
+
operations = yield({})
|
|
146
|
+
persist_or_delay_atomic_operation(operations)
|
|
147
|
+
self
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Process the atomic operations - this handles the common behaviour of
|
|
151
|
+
# iterating through each op, getting the aliased field name, and removing
|
|
152
|
+
# appropriate dirty changes.
|
|
153
|
+
#
|
|
154
|
+
# @api private
|
|
155
|
+
#
|
|
156
|
+
# @example Process the atomic operations.
|
|
157
|
+
# document.process_atomic_operations(pulls) do |field, value|
|
|
158
|
+
# ...
|
|
159
|
+
# end
|
|
160
|
+
#
|
|
161
|
+
# @param [ Hash ] operations The atomic operations.
|
|
162
|
+
#
|
|
163
|
+
# @return [ Hash ] The operations.
|
|
164
|
+
#
|
|
165
|
+
# @since 4.0.0
|
|
166
|
+
def process_atomic_operations(operations)
|
|
167
|
+
operations.each do |field, value|
|
|
168
|
+
unless attribute_writable?(field)
|
|
169
|
+
raise Errors::ReadonlyAttribute.new(field, value)
|
|
170
|
+
end
|
|
171
|
+
normalized = database_field_name(field)
|
|
172
|
+
yield(normalized, value)
|
|
173
|
+
remove_change(normalized)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# If we are in an atomically block, add the operations to the delayed group,
|
|
178
|
+
# otherwise persist immediately.
|
|
179
|
+
#
|
|
180
|
+
# @api private
|
|
181
|
+
#
|
|
182
|
+
# @example Persist immediately or delay the operations.
|
|
183
|
+
# document.persist_or_delay_atomic_operation(ops)
|
|
184
|
+
#
|
|
185
|
+
# @param [ Hash ] operation The operation.
|
|
186
|
+
#
|
|
187
|
+
# @since 4.0.0
|
|
188
|
+
def persist_or_delay_atomic_operation(operation)
|
|
189
|
+
if executing_atomically?
|
|
190
|
+
operation.each do |(name, hash)|
|
|
191
|
+
@atomic_updates_to_execute[name] ||= {}
|
|
192
|
+
@atomic_updates_to_execute[name].merge!(hash)
|
|
193
|
+
end
|
|
194
|
+
else
|
|
195
|
+
persist_atomic_operations(operation)
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
# Persist the atomic operations.
|
|
200
|
+
#
|
|
201
|
+
# @api private
|
|
202
|
+
#
|
|
203
|
+
# @example Persist the atomic operations.
|
|
204
|
+
# persist_atomic_operations(ops)
|
|
205
|
+
#
|
|
206
|
+
# @param [ Hash ] operations The atomic operations.
|
|
207
|
+
#
|
|
208
|
+
# @since 4.0.0
|
|
209
|
+
def persist_atomic_operations(operations)
|
|
210
|
+
if persisted?
|
|
211
|
+
selector = atomic_selector
|
|
212
|
+
_root.collection.find(selector).update(positionally(selector, operations))
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|