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
|
@@ -33,19 +33,6 @@ module Mongoid
|
|
|
33
33
|
def insert_modifier
|
|
34
34
|
raise Errors::InvalidPath.new(document.class)
|
|
35
35
|
end
|
|
36
|
-
|
|
37
|
-
# Get the selector to use for the root document when performing atomic
|
|
38
|
-
# updates. When sharding this will include the shard key.
|
|
39
|
-
#
|
|
40
|
-
# @example Get the selector.
|
|
41
|
-
# root.selector
|
|
42
|
-
#
|
|
43
|
-
# @return [ Hash ] The selector to identify the document with.
|
|
44
|
-
#
|
|
45
|
-
# @since 2.1.0
|
|
46
|
-
def selector
|
|
47
|
-
@selector ||= { "_id" => document._id }.merge!(document.shard_key_selector)
|
|
48
|
-
end
|
|
49
36
|
end
|
|
50
37
|
end
|
|
51
38
|
end
|
data/lib/mongoid/atomic.rb
CHANGED
|
@@ -189,7 +189,7 @@ module Mongoid
|
|
|
189
189
|
#
|
|
190
190
|
# @since 2.1.0
|
|
191
191
|
def atomic_paths
|
|
192
|
-
@atomic_paths ||=
|
|
192
|
+
@atomic_paths ||= __metadata ? __metadata.path(self) : Atomic::Paths::Root.new(self)
|
|
193
193
|
end
|
|
194
194
|
|
|
195
195
|
# Get all the attributes that need to be pulled.
|
|
@@ -225,17 +225,6 @@ module Mongoid
|
|
|
225
225
|
pushable? ? { atomic_position => as_document } : {}
|
|
226
226
|
end
|
|
227
227
|
|
|
228
|
-
# Return the selector for this document to be matched exactly for use
|
|
229
|
-
# with MongoDB's $ operator.
|
|
230
|
-
#
|
|
231
|
-
# @example Get the selector.
|
|
232
|
-
# address.atomic_selector
|
|
233
|
-
#
|
|
234
|
-
# @return [ String ] The exact selector for this document.
|
|
235
|
-
def atomic_selector
|
|
236
|
-
atomic_paths.selector
|
|
237
|
-
end
|
|
238
|
-
|
|
239
228
|
# Get all the attributes that need to be set.
|
|
240
229
|
#
|
|
241
230
|
# @example Get the sets.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Attributes
|
|
4
|
+
|
|
5
|
+
# This module contains the behavior for dynamic attributes.
|
|
6
|
+
#
|
|
7
|
+
# @since 4.0.0
|
|
8
|
+
module Dynamic
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
# Override respond_to? so it responds properly for dynamic attributes.
|
|
12
|
+
#
|
|
13
|
+
# @example Does this object respond to the method?
|
|
14
|
+
# person.respond_to?(:title)
|
|
15
|
+
#
|
|
16
|
+
# @param [ Array ] *args The name of the method.
|
|
17
|
+
#
|
|
18
|
+
# @return [ true, false ] True if it does, false if not.
|
|
19
|
+
#
|
|
20
|
+
# @since 4.0.0
|
|
21
|
+
def respond_to?(name, include_private = false)
|
|
22
|
+
super || (
|
|
23
|
+
attributes &&
|
|
24
|
+
attributes.has_key?(name.to_s.reader)
|
|
25
|
+
)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Define a reader method for a dynamic attribute.
|
|
29
|
+
#
|
|
30
|
+
# @api private
|
|
31
|
+
#
|
|
32
|
+
# @example Define a reader method.
|
|
33
|
+
# model.define_dynamic_reader(:field)
|
|
34
|
+
#
|
|
35
|
+
# @param [ String ] name The name of the field.
|
|
36
|
+
#
|
|
37
|
+
# @since 4.0.0
|
|
38
|
+
def define_dynamic_reader(name)
|
|
39
|
+
return unless name.valid_method_name?
|
|
40
|
+
class_eval <<-READER
|
|
41
|
+
def #{name}
|
|
42
|
+
attribute_will_change!(#{name.inspect})
|
|
43
|
+
read_attribute(#{name.inspect})
|
|
44
|
+
end
|
|
45
|
+
READER
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Define a reader method for a dynamic attribute before type cast.
|
|
49
|
+
#
|
|
50
|
+
# @api private
|
|
51
|
+
#
|
|
52
|
+
# @example Define a reader method for an attribute.
|
|
53
|
+
# model.define_dynamic_before_type_cast_reader(:field)
|
|
54
|
+
#
|
|
55
|
+
# @param [ String ] name The name of the field.
|
|
56
|
+
#
|
|
57
|
+
# @since 4.0.0
|
|
58
|
+
def define_dynamic_before_type_cast_reader(name)
|
|
59
|
+
class_eval <<-READER
|
|
60
|
+
def #{name}_before_type_cast
|
|
61
|
+
attribute_will_change!(#{name.inspect})
|
|
62
|
+
read_attribute_before_type_cast(#{name.inspect})
|
|
63
|
+
end
|
|
64
|
+
READER
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Define a writer method for a dynamic attribute.
|
|
68
|
+
#
|
|
69
|
+
# @api private
|
|
70
|
+
#
|
|
71
|
+
# @example Define a writer method.
|
|
72
|
+
# model.define_dynamic_writer(:field)
|
|
73
|
+
#
|
|
74
|
+
# @param [ String ] name The name of the field.
|
|
75
|
+
#
|
|
76
|
+
# @since 4.0.0
|
|
77
|
+
def define_dynamic_writer(name)
|
|
78
|
+
return unless name.valid_method_name?
|
|
79
|
+
|
|
80
|
+
class_eval <<-WRITER
|
|
81
|
+
def #{name}=(value)
|
|
82
|
+
write_attribute(#{name.inspect}, value)
|
|
83
|
+
end
|
|
84
|
+
WRITER
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# If the attribute is dynamic, add a field for it with a type of object
|
|
88
|
+
# and set the value.
|
|
89
|
+
#
|
|
90
|
+
# @example Process the attribute.
|
|
91
|
+
# document.process_attribute(name, value)
|
|
92
|
+
#
|
|
93
|
+
# @param [ Symbol ] name The name of the field.
|
|
94
|
+
# @param [ Object ] value The value of the field.
|
|
95
|
+
#
|
|
96
|
+
# @since 4.0.0
|
|
97
|
+
def process_attribute(name, value)
|
|
98
|
+
responds = respond_to?("#{name}=")
|
|
99
|
+
if !responds
|
|
100
|
+
write_attribute(name, value)
|
|
101
|
+
else
|
|
102
|
+
send("#{name}=", value)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Get an array of inspected dynamic fields for the document.
|
|
107
|
+
#
|
|
108
|
+
# @example Inspect the dynamic fields.
|
|
109
|
+
# document.inspect_dynamic_fields
|
|
110
|
+
#
|
|
111
|
+
# @return [ String ] An array of pretty printed dynamic field values.
|
|
112
|
+
#
|
|
113
|
+
# @since 4.0.0
|
|
114
|
+
def inspect_dynamic_fields
|
|
115
|
+
keys = attributes.keys - fields.keys - relations.keys - ["_id", "_type"]
|
|
116
|
+
return keys.map do |name|
|
|
117
|
+
"#{name}: #{attributes[name].inspect}"
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Used for allowing accessor methods for dynamic attributes.
|
|
122
|
+
#
|
|
123
|
+
# @api private
|
|
124
|
+
#
|
|
125
|
+
# @example Call through method_missing.
|
|
126
|
+
# document.method_missing(:test)
|
|
127
|
+
#
|
|
128
|
+
# @param [ String, Symbol ] name The name of the method.
|
|
129
|
+
# @param [ Array ] *args The arguments to the method.
|
|
130
|
+
#
|
|
131
|
+
# @return [ Object ] The result of the method call.
|
|
132
|
+
#
|
|
133
|
+
# @since 4.0.0
|
|
134
|
+
def method_missing(name, *args)
|
|
135
|
+
attr = name.to_s
|
|
136
|
+
return super unless attributes.has_key?(attr.reader)
|
|
137
|
+
if attr.writer?
|
|
138
|
+
getter = attr.reader
|
|
139
|
+
define_dynamic_writer(getter)
|
|
140
|
+
write_attribute(getter, args.first)
|
|
141
|
+
elsif attr.before_type_cast?
|
|
142
|
+
define_dynamic_before_type_cast_reader(attr.reader)
|
|
143
|
+
attribute_will_change!(attr.reader)
|
|
144
|
+
read_attribute_before_type_cast(attr.reader)
|
|
145
|
+
else
|
|
146
|
+
getter = attr.reader
|
|
147
|
+
define_dynamic_reader(getter)
|
|
148
|
+
attribute_will_change!(attr.reader)
|
|
149
|
+
read_attribute(getter)
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
end
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# encoding: utf-8
|
|
2
|
+
module Mongoid
|
|
3
|
+
module Attributes
|
|
4
|
+
|
|
5
|
+
# Defines behaviour around that lovel Rails feature nested attributes.
|
|
6
|
+
#
|
|
7
|
+
# @since 1.0.0
|
|
8
|
+
module Nested
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
included do
|
|
12
|
+
class_attribute :nested_attributes
|
|
13
|
+
self.nested_attributes = {}
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
module ClassMethods
|
|
17
|
+
|
|
18
|
+
REJECT_ALL_BLANK_PROC = ->(attributes){
|
|
19
|
+
attributes.all? { |key, value| key == '_destroy' || value.blank? }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Used when needing to update related models from a parent relation. Can
|
|
23
|
+
# be used on embedded or referenced relations.
|
|
24
|
+
#
|
|
25
|
+
# @example Defining nested attributes.
|
|
26
|
+
#
|
|
27
|
+
# class Person
|
|
28
|
+
# include Mongoid::Document
|
|
29
|
+
#
|
|
30
|
+
# embeds_many :addresses
|
|
31
|
+
# embeds_one :game
|
|
32
|
+
# references_many :posts
|
|
33
|
+
#
|
|
34
|
+
# accepts_nested_attributes_for :addresses, :game, :posts
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# @param [ Array<Symbol>, Hash ] *args A list of relation names, followed
|
|
38
|
+
# by a hash of options.
|
|
39
|
+
#
|
|
40
|
+
# @option *args [ true, false ] :allow_destroy Can deletion occur?
|
|
41
|
+
# @option *args [ Proc, Symbol ] :reject_if Block or symbol pointing
|
|
42
|
+
# to a class method to reject documents with.
|
|
43
|
+
# @option *args [ Integer ] :limit The max number to create.
|
|
44
|
+
# @option *args [ true, false ] :update_only Only update existing docs.
|
|
45
|
+
def accepts_nested_attributes_for(*args)
|
|
46
|
+
options = args.extract_options!
|
|
47
|
+
options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
|
|
48
|
+
args.each do |name|
|
|
49
|
+
meth = "#{name}_attributes="
|
|
50
|
+
self.nested_attributes["#{name}_attributes"] = meth
|
|
51
|
+
metadata = relations[name.to_s]
|
|
52
|
+
raise Errors::NestedAttributesMetadataNotFound.new(self, name) unless metadata
|
|
53
|
+
autosave_nested_attributes(metadata)
|
|
54
|
+
re_define_method(meth) do |attrs|
|
|
55
|
+
_assigning do
|
|
56
|
+
metadata.nested_builder(attrs, options).build(self)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# Add the autosave information for the nested relation.
|
|
65
|
+
#
|
|
66
|
+
# @api private
|
|
67
|
+
#
|
|
68
|
+
# @example Add the autosave if appropriate.
|
|
69
|
+
# Person.autosave_nested_attributes(metadata)
|
|
70
|
+
#
|
|
71
|
+
# @param [ Metadata ] metadata The existing relation metadata.
|
|
72
|
+
#
|
|
73
|
+
# @since 3.1.4
|
|
74
|
+
def autosave_nested_attributes(metadata)
|
|
75
|
+
unless metadata.autosave == false
|
|
76
|
+
autosave(metadata.merge!(autosave: true))
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -14,49 +14,23 @@ module Mongoid
|
|
|
14
14
|
# person.process_attributes(:title => "sir", :age => 40)
|
|
15
15
|
#
|
|
16
16
|
# @param [ Hash ] attrs The attributes to set.
|
|
17
|
-
# @param [ Symbol ] role A role for scoped mass assignment.
|
|
18
|
-
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
|
19
17
|
#
|
|
20
18
|
# @since 2.0.0.rc.7
|
|
21
|
-
def process_attributes(attrs = nil
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
process_attribute(key, value)
|
|
29
|
-
end
|
|
19
|
+
def process_attributes(attrs = nil)
|
|
20
|
+
attrs ||= {}
|
|
21
|
+
if !attrs.empty?
|
|
22
|
+
attrs = sanitize_for_mass_assignment(attrs)
|
|
23
|
+
attrs.each_pair do |key, value|
|
|
24
|
+
next if pending_attribute?(key, value)
|
|
25
|
+
process_attribute(key, value)
|
|
30
26
|
end
|
|
31
|
-
yield self if block_given?
|
|
32
|
-
process_pending
|
|
33
27
|
end
|
|
28
|
+
yield self if block_given?
|
|
29
|
+
process_pending
|
|
34
30
|
end
|
|
35
31
|
|
|
36
32
|
private
|
|
37
33
|
|
|
38
|
-
# Get the current mass assignment options for this model.
|
|
39
|
-
#
|
|
40
|
-
# @api private
|
|
41
|
-
#
|
|
42
|
-
# @return [ Hash ] The mass assignment options.
|
|
43
|
-
#
|
|
44
|
-
# @since 3.0.7
|
|
45
|
-
def mass_assignment_options
|
|
46
|
-
@mass_assignment_options ||= {}
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Set the mass assignment options for the current model.
|
|
50
|
-
#
|
|
51
|
-
# @api private
|
|
52
|
-
#
|
|
53
|
-
# @return [ Hash ] The mass assignment options.
|
|
54
|
-
#
|
|
55
|
-
# @since 3.0.7
|
|
56
|
-
def mass_assignment_options=(options)
|
|
57
|
-
@mass_assignment_options = options
|
|
58
|
-
end
|
|
59
|
-
|
|
60
34
|
# If the key provided is the name of a relation or a nested attribute, we
|
|
61
35
|
# need to wait until all other attributes are set before processing
|
|
62
36
|
# these.
|
|
@@ -118,14 +92,9 @@ module Mongoid
|
|
|
118
92
|
#
|
|
119
93
|
# @since 2.0.0.rc.7
|
|
120
94
|
def process_attribute(name, value)
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
write_attribute(name, value)
|
|
125
|
-
else
|
|
126
|
-
raise Errors::UnknownAttribute.new(self.class, name) unless responds
|
|
127
|
-
send(writer_method, value)
|
|
128
|
-
end
|
|
95
|
+
responds = respond_to?("#{name}=")
|
|
96
|
+
raise Errors::UnknownAttribute.new(self.class, name) unless responds
|
|
97
|
+
send("#{name}=", value)
|
|
129
98
|
end
|
|
130
99
|
|
|
131
100
|
# Process all the pending nested attributes that needed to wait until
|
|
@@ -167,34 +136,12 @@ module Mongoid
|
|
|
167
136
|
pending_relations.each_pair do |name, value|
|
|
168
137
|
metadata = relations[name]
|
|
169
138
|
if value.is_a?(Hash)
|
|
170
|
-
metadata.nested_builder(value, {}).build(self
|
|
139
|
+
metadata.nested_builder(value, {}).build(self)
|
|
171
140
|
else
|
|
172
141
|
send("#{name}=", value)
|
|
173
142
|
end
|
|
174
143
|
end
|
|
175
144
|
end
|
|
176
|
-
|
|
177
|
-
# Execute the block with the provided mass assignment options set.
|
|
178
|
-
#
|
|
179
|
-
# @api private
|
|
180
|
-
#
|
|
181
|
-
# @example Execute with mass assignment.
|
|
182
|
-
# model.with_mass_assignment(:default, true)
|
|
183
|
-
#
|
|
184
|
-
# @param [ Symbol ] role The role.
|
|
185
|
-
# @param [ true, false ] guard_protected_attributes To enable mass
|
|
186
|
-
# assignment.
|
|
187
|
-
#
|
|
188
|
-
# @since 3.0.7
|
|
189
|
-
def with_mass_assignment(role, guard_protected_attributes)
|
|
190
|
-
begin
|
|
191
|
-
self.mass_assignment_options =
|
|
192
|
-
{ as: role, without_protection: !guard_protected_attributes }
|
|
193
|
-
yield
|
|
194
|
-
ensure
|
|
195
|
-
self.mass_assignment_options = nil
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
145
|
end
|
|
199
146
|
end
|
|
200
147
|
end
|
data/lib/mongoid/attributes.rb
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
# encoding: utf-8
|
|
2
|
+
require "active_model/attribute_methods"
|
|
3
|
+
require "mongoid/attributes/dynamic"
|
|
4
|
+
require "mongoid/attributes/nested"
|
|
2
5
|
require "mongoid/attributes/processing"
|
|
3
6
|
require "mongoid/attributes/readonly"
|
|
4
7
|
|
|
@@ -8,6 +11,7 @@ module Mongoid
|
|
|
8
11
|
# and how to get and set values.
|
|
9
12
|
module Attributes
|
|
10
13
|
extend ActiveSupport::Concern
|
|
14
|
+
include Nested
|
|
11
15
|
include Processing
|
|
12
16
|
include Readonly
|
|
13
17
|
|
|
@@ -86,7 +90,10 @@ module Mongoid
|
|
|
86
90
|
#
|
|
87
91
|
# @since 1.0.0
|
|
88
92
|
def read_attribute(name)
|
|
89
|
-
normalized = name.to_s
|
|
93
|
+
normalized = database_field_name(name.to_s)
|
|
94
|
+
if attribute_missing?(normalized)
|
|
95
|
+
raise ActiveModel::MissingAttributeError, "Missing attribute: '#{name}'."
|
|
96
|
+
end
|
|
90
97
|
if hash_dot_syntax?(normalized)
|
|
91
98
|
attributes.__nested__(normalized)
|
|
92
99
|
else
|
|
@@ -141,25 +148,6 @@ module Mongoid
|
|
|
141
148
|
end
|
|
142
149
|
end
|
|
143
150
|
|
|
144
|
-
# Override respond_to? so it responds properly for dynamic attributes.
|
|
145
|
-
#
|
|
146
|
-
# @example Does this object respond to the method?
|
|
147
|
-
# person.respond_to?(:title)
|
|
148
|
-
#
|
|
149
|
-
# @param [ Array ] *args The name of the method.
|
|
150
|
-
#
|
|
151
|
-
# @return [ true, false ] True if it does, false if not.
|
|
152
|
-
#
|
|
153
|
-
# @since 1.0.0
|
|
154
|
-
def respond_to?(name, include_private = false)
|
|
155
|
-
super || (
|
|
156
|
-
Mongoid.allow_dynamic_fields &&
|
|
157
|
-
attributes &&
|
|
158
|
-
attributes.has_key?(name.to_s.reader) &&
|
|
159
|
-
name.to_s.valid_method_name?
|
|
160
|
-
)
|
|
161
|
-
end
|
|
162
|
-
|
|
163
151
|
# Write a single attribute to the document attribute hash. This will
|
|
164
152
|
# also fire the before and after update callbacks, and perform any
|
|
165
153
|
# necessary typecasting.
|
|
@@ -178,6 +166,7 @@ module Mongoid
|
|
|
178
166
|
access = database_field_name(name.to_s)
|
|
179
167
|
if attribute_writable?(access)
|
|
180
168
|
_assigning do
|
|
169
|
+
validate_attribute_value(access, value)
|
|
181
170
|
localized = fields[access].try(:localized?)
|
|
182
171
|
attributes_before_type_cast[name.to_s] = value
|
|
183
172
|
typed_value = typed_value_for(access, value)
|
|
@@ -207,12 +196,11 @@ module Mongoid
|
|
|
207
196
|
# person.assign_attributes({ :title => "Mr." }, :as => :admin)
|
|
208
197
|
#
|
|
209
198
|
# @param [ Hash ] attrs The new attributes to set.
|
|
210
|
-
# @param [ Hash ] options Supported options: :without_protection, :as
|
|
211
199
|
#
|
|
212
200
|
# @since 2.2.1
|
|
213
|
-
def assign_attributes(attrs = nil
|
|
201
|
+
def assign_attributes(attrs = nil)
|
|
214
202
|
_assigning do
|
|
215
|
-
process_attributes(attrs
|
|
203
|
+
process_attributes(attrs)
|
|
216
204
|
end
|
|
217
205
|
end
|
|
218
206
|
|
|
@@ -230,71 +218,46 @@ module Mongoid
|
|
|
230
218
|
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
|
231
219
|
#
|
|
232
220
|
# @since 1.0.0
|
|
233
|
-
def write_attributes(attrs = nil
|
|
234
|
-
assign_attributes(attrs
|
|
221
|
+
def write_attributes(attrs = nil)
|
|
222
|
+
assign_attributes(attrs)
|
|
235
223
|
end
|
|
236
224
|
alias :attributes= :write_attributes
|
|
237
225
|
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
# Define a reader method for a dynamic attribute.
|
|
226
|
+
# Determine if the attribute is missing from the document, due to loading
|
|
227
|
+
# it from the database with missing fields.
|
|
241
228
|
#
|
|
242
|
-
# @
|
|
229
|
+
# @example Is the attribute missing?
|
|
230
|
+
# document.attribute_missing?("test")
|
|
243
231
|
#
|
|
244
|
-
# @
|
|
245
|
-
# model.define_dynamic_reader(:field)
|
|
232
|
+
# @param [ String ] name The name of the attribute.
|
|
246
233
|
#
|
|
247
|
-
# @
|
|
234
|
+
# @return [ true, false ] If the attribute is missing.
|
|
248
235
|
#
|
|
249
|
-
# @since
|
|
250
|
-
def
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
read_attribute(#{name.inspect})
|
|
257
|
-
end
|
|
258
|
-
READER
|
|
236
|
+
# @since 4.0.0
|
|
237
|
+
def attribute_missing?(name)
|
|
238
|
+
selection = __selected_fields
|
|
239
|
+
return false unless selection
|
|
240
|
+
field = fields[name]
|
|
241
|
+
(selection.values.first == 0 && selection_excluded?(name, selection, field)) ||
|
|
242
|
+
(selection.values.first == 1 && !selection_included?(name, selection, field))
|
|
259
243
|
end
|
|
260
244
|
|
|
261
|
-
|
|
262
|
-
#
|
|
263
|
-
# @api private
|
|
264
|
-
#
|
|
265
|
-
# @example Define a reader method for an attribute.
|
|
266
|
-
# model.define_dynamic_before_type_cast_reader(:field)
|
|
267
|
-
#
|
|
268
|
-
# @param [ String ] name The name of the field.
|
|
269
|
-
#
|
|
270
|
-
# @since 3.1.0
|
|
271
|
-
def define_dynamic_before_type_cast_reader(name)
|
|
272
|
-
class_eval <<-READER
|
|
273
|
-
def #{name}_before_type_cast
|
|
274
|
-
attribute_will_change!(#{name.inspect})
|
|
275
|
-
read_attribute_before_type_cast(#{name.inspect})
|
|
276
|
-
end
|
|
277
|
-
READER
|
|
278
|
-
end
|
|
245
|
+
private
|
|
279
246
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
# @param [ String ] name The name of the field.
|
|
288
|
-
#
|
|
289
|
-
# @since 3.0.0
|
|
290
|
-
def define_dynamic_writer(name)
|
|
291
|
-
return unless name.valid_method_name?
|
|
247
|
+
def selection_excluded?(name, selection, field)
|
|
248
|
+
if field && field.localized?
|
|
249
|
+
selection["#{name}.#{::I18n.locale}"] == 0
|
|
250
|
+
else
|
|
251
|
+
selection[name] == 0
|
|
252
|
+
end
|
|
253
|
+
end
|
|
292
254
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
255
|
+
def selection_included?(name, selection, field)
|
|
256
|
+
if field && field.localized?
|
|
257
|
+
selection.has_key?("#{name}.#{::I18n.locale}")
|
|
258
|
+
else
|
|
259
|
+
selection.has_key?(name)
|
|
260
|
+
end
|
|
298
261
|
end
|
|
299
262
|
|
|
300
263
|
# Does the string contain dot syntax for accessing hashes?
|
|
@@ -308,30 +271,7 @@ module Mongoid
|
|
|
308
271
|
#
|
|
309
272
|
# @since 3.0.15
|
|
310
273
|
def hash_dot_syntax?(string)
|
|
311
|
-
string
|
|
312
|
-
end
|
|
313
|
-
|
|
314
|
-
# Used for allowing accessor methods for dynamic attributes.
|
|
315
|
-
#
|
|
316
|
-
# @param [ String, Symbol ] name The name of the method.
|
|
317
|
-
# @param [ Array ] *args The arguments to the method.
|
|
318
|
-
def method_missing(name, *args)
|
|
319
|
-
attr = name.to_s
|
|
320
|
-
return super unless attributes.has_key?(attr.reader)
|
|
321
|
-
if attr.writer?
|
|
322
|
-
getter = attr.reader
|
|
323
|
-
define_dynamic_writer(getter)
|
|
324
|
-
write_attribute(getter, args.first)
|
|
325
|
-
elsif attr.before_type_cast?
|
|
326
|
-
define_dynamic_before_type_cast_reader(attr.reader)
|
|
327
|
-
attribute_will_change!(attr.reader)
|
|
328
|
-
read_attribute_before_type_cast(attr.reader)
|
|
329
|
-
else
|
|
330
|
-
getter = attr.reader
|
|
331
|
-
define_dynamic_reader(getter)
|
|
332
|
-
attribute_will_change!(attr.reader)
|
|
333
|
-
read_attribute(getter)
|
|
334
|
-
end
|
|
274
|
+
string.include?(".")
|
|
335
275
|
end
|
|
336
276
|
|
|
337
277
|
# Return the typecasted value for a field.
|
|
@@ -367,6 +307,7 @@ module Mongoid
|
|
|
367
307
|
#
|
|
368
308
|
# @since 2.3.0
|
|
369
309
|
def alias_attribute(name, original)
|
|
310
|
+
aliased_fields[name.to_s] = original.to_s
|
|
370
311
|
class_eval <<-RUBY
|
|
371
312
|
alias #{name} #{original}
|
|
372
313
|
alias #{name}= #{original}=
|
|
@@ -374,11 +315,32 @@ module Mongoid
|
|
|
374
315
|
alias #{name}_change #{original}_change
|
|
375
316
|
alias #{name}_changed? #{original}_changed?
|
|
376
317
|
alias reset_#{name}! reset_#{original}!
|
|
318
|
+
alias reset_#{name}_to_default! reset_#{original}_to_default!
|
|
377
319
|
alias #{name}_was #{original}_was
|
|
378
320
|
alias #{name}_will_change! #{original}_will_change!
|
|
379
321
|
alias #{name}_before_type_cast #{original}_before_type_cast
|
|
380
322
|
RUBY
|
|
381
323
|
end
|
|
382
324
|
end
|
|
325
|
+
|
|
326
|
+
private
|
|
327
|
+
|
|
328
|
+
# Validates an attribute value. This provides validation checking if
|
|
329
|
+
# the value is valid for given a field.
|
|
330
|
+
# For now, only Hash and Array fields are validated.
|
|
331
|
+
#
|
|
332
|
+
# @param [ String, Symbol ] name The name of the attribute to validate.
|
|
333
|
+
# @param [ Object ] value The to be validated.
|
|
334
|
+
#
|
|
335
|
+
# @since 3.0.10
|
|
336
|
+
def validate_attribute_value(access, value)
|
|
337
|
+
return unless fields[access] && value
|
|
338
|
+
validatable_types = [ Hash, Array ]
|
|
339
|
+
if validatable_types.include? fields[access].type
|
|
340
|
+
unless value.is_a? fields[access].type
|
|
341
|
+
raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
|
|
342
|
+
end
|
|
343
|
+
end
|
|
344
|
+
end
|
|
383
345
|
end
|
|
384
346
|
end
|