mongoid 3.1.7 → 4.0.0.alpha1
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 +317 -11
- data/README.md +4 -5
- data/lib/config/locales/en.yml +9 -12
- data/lib/mongoid.rb +6 -75
- data/lib/mongoid/atomic.rb +0 -11
- data/lib/mongoid/atomic/paths/embedded.rb +0 -30
- data/lib/mongoid/atomic/paths/root.rb +0 -13
- data/lib/mongoid/attributes.rb +30 -108
- data/lib/mongoid/attributes/dynamic.rb +154 -0
- data/lib/mongoid/attributes/nested.rb +82 -0
- data/lib/mongoid/attributes/processing.rb +13 -66
- data/lib/mongoid/{dirty.rb → changeable.rb} +5 -2
- data/lib/mongoid/composable.rb +104 -0
- data/lib/mongoid/config.rb +3 -9
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/contextual/aggregable/mongo.rb +5 -9
- data/lib/mongoid/contextual/atomic.rb +53 -53
- data/lib/mongoid/contextual/command.rb +26 -0
- data/lib/mongoid/contextual/map_reduce.rb +1 -1
- data/lib/mongoid/contextual/memory.rb +6 -5
- data/lib/mongoid/contextual/mongo.rb +59 -28
- data/lib/mongoid/contextual/text_search.rb +180 -0
- data/lib/mongoid/copyable.rb +2 -3
- data/lib/mongoid/criteria.rb +13 -33
- data/lib/mongoid/criteria/{#findable.rb# → findable.rb} +0 -2
- 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 +1 -1
- data/lib/mongoid/{criterion/scoping.rb → criteria/scopable.rb} +2 -2
- data/lib/mongoid/document.rb +28 -12
- data/lib/mongoid/errors.rb +1 -1
- data/lib/mongoid/errors/document_not_found.rb +2 -1
- data/lib/mongoid/errors/invalid_value.rb +16 -0
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/extensions.rb +2 -7
- data/lib/mongoid/extensions/array.rb +2 -2
- data/lib/mongoid/extensions/boolean.rb +14 -17
- data/lib/mongoid/extensions/float.rb +1 -0
- data/lib/mongoid/extensions/hash.rb +1 -1
- data/lib/mongoid/extensions/object.rb +4 -4
- data/lib/mongoid/extensions/object_id.rb +5 -5
- data/lib/mongoid/extensions/range.rb +8 -2
- data/lib/mongoid/extensions/string.rb +5 -17
- data/lib/mongoid/extensions/time.rb +2 -2
- data/lib/mongoid/factory.rb +3 -3
- data/lib/mongoid/fields.rb +9 -8
- data/lib/mongoid/fields/foreign_key.rb +3 -3
- data/lib/mongoid/fields/standard.rb +4 -16
- data/lib/mongoid/fields/validators/macro.rb +11 -3
- data/lib/mongoid/{finders.rb → findable.rb} +6 -2
- data/lib/mongoid/{indexes.rb → indexable.rb} +50 -55
- data/lib/mongoid/indexable/specification.rb +104 -0
- data/lib/mongoid/{indexes → indexable}/validators/options.rb +2 -1
- data/lib/mongoid/{inspection.rb → inspectable.rb} +15 -11
- data/lib/mongoid/{callbacks.rb → interceptable.rb} +3 -52
- data/lib/mongoid/log_subscriber.rb +22 -0
- data/lib/mongoid/matchable.rb +152 -0
- data/lib/mongoid/{matchers → matchable}/all.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/and.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/default.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/exists.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/gt.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/gte.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/in.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/lt.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/lte.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/ne.rb +1 -1
- data/lib/mongoid/{matchers → matchable}/nin.rb +3 -2
- data/lib/mongoid/{matchers → matchable}/or.rb +2 -2
- data/lib/mongoid/{matchers → matchable}/size.rb +1 -1
- data/lib/mongoid/persistable.rb +212 -0
- data/lib/mongoid/persistable/creatable.rb +188 -0
- data/lib/mongoid/persistable/deletable.rb +148 -0
- data/lib/mongoid/persistable/destroyable.rb +55 -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 +151 -0
- data/lib/mongoid/persistable/upsertable.rb +55 -0
- data/lib/mongoid/positional.rb +71 -0
- data/lib/mongoid/railtie.rb +32 -45
- data/lib/mongoid/railties/database.rake +12 -6
- data/lib/mongoid/relations.rb +3 -3
- data/lib/mongoid/relations/accessors.rb +13 -46
- data/lib/mongoid/relations/auto_save.rb +15 -36
- data/lib/mongoid/relations/binding.rb +0 -23
- 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.rb +2 -2
- 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/cascading.rb +3 -5
- data/lib/mongoid/relations/constraint.rb +1 -1
- data/lib/mongoid/relations/conversions.rb +1 -1
- data/lib/mongoid/relations/counter_cache.rb +39 -15
- data/lib/mongoid/relations/eager.rb +47 -0
- data/lib/mongoid/relations/eager/base.rb +57 -0
- data/lib/mongoid/relations/eager/belongs_to.rb +30 -0
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +40 -0
- data/lib/mongoid/relations/eager/has_many.rb +37 -0
- data/lib/mongoid/relations/eager/has_one.rb +29 -0
- data/lib/mongoid/relations/embedded/batchable.rb +3 -4
- data/lib/mongoid/relations/embedded/many.rb +7 -27
- data/lib/mongoid/relations/macros.rb +2 -4
- data/lib/mongoid/relations/many.rb +30 -31
- data/lib/mongoid/relations/metadata.rb +6 -75
- 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 +10 -32
- data/lib/mongoid/relations/referenced/in.rb +2 -18
- data/lib/mongoid/relations/referenced/many.rb +9 -22
- data/lib/mongoid/relations/referenced/many_to_many.rb +10 -33
- data/lib/mongoid/relations/referenced/one.rb +2 -21
- data/lib/mongoid/relations/synchronization.rb +3 -3
- data/lib/mongoid/relations/touchable.rb +33 -0
- data/lib/mongoid/{reloading.rb → reloadable.rb} +6 -4
- data/lib/mongoid/{scoping.rb → scopable.rb} +26 -3
- data/lib/mongoid/selectable.rb +59 -0
- data/lib/mongoid/{serialization.rb → serializable.rb} +10 -1
- data/lib/mongoid/sessions.rb +37 -345
- data/lib/mongoid/sessions/factory.rb +2 -0
- data/lib/mongoid/sessions/options.rb +176 -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 +15 -1
- data/lib/mongoid/{sharding.rb → shardable.rb} +5 -1
- data/lib/mongoid/support/query_counter.rb +23 -0
- data/lib/mongoid/threaded.rb +0 -110
- data/lib/mongoid/threaded/lifecycle.rb +0 -28
- data/lib/mongoid/timestamps/updated/short.rb +2 -2
- data/lib/mongoid/{hierarchy.rb → traversable.rb} +9 -5
- data/lib/mongoid/{validations.rb → validatable.rb} +23 -9
- data/lib/mongoid/{validations → validatable}/associated.rb +3 -1
- 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 +3 -3
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +9 -13
- 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 +59 -57
- data/lib/support/ruby_version.rb +1 -1
- data/spec/app/models/account.rb +2 -6
- data/spec/app/models/acolyte.rb +1 -0
- data/spec/app/models/actor.rb +0 -1
- data/spec/app/models/address.rb +6 -1
- data/spec/app/models/animal.rb +1 -1
- data/spec/app/models/appointment.rb +2 -2
- 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/dragon.rb +4 -0
- data/spec/app/models/drug.rb +1 -3
- data/spec/app/models/dungeon.rb +4 -0
- 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 +0 -2
- 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/login.rb +1 -1
- data/spec/app/models/movie.rb +1 -0
- data/spec/app/models/name.rb +3 -3
- data/spec/app/models/note.rb +1 -1
- data/spec/app/models/oscar.rb +1 -1
- data/spec/app/models/parent_doc.rb +1 -1
- data/spec/app/models/person.rb +13 -8
- data/spec/app/models/phone.rb +1 -3
- data/spec/app/models/player.rb +1 -1
- data/spec/app/models/post.rb +2 -1
- data/spec/app/models/quiz.rb +0 -3
- data/spec/app/models/record.rb +5 -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/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 +1 -1
- data/spec/app/models/video.rb +0 -4
- data/spec/app/models/wiki_page.rb +1 -4
- 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 +16 -16
- data/spec/mongoid/attributes_spec.rb +188 -434
- data/spec/mongoid/{dirty_spec.rb → changeable_spec.rb} +117 -148
- 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 +46 -38
- data/spec/mongoid/contextual/atomic_spec.rb +60 -56
- data/spec/mongoid/contextual/find_and_modify_spec.rb +14 -14
- data/spec/mongoid/contextual/geo_near_spec.rb +22 -22
- data/spec/mongoid/contextual/map_reduce_spec.rb +27 -27
- data/spec/mongoid/contextual/memory_spec.rb +94 -94
- data/spec/mongoid/contextual/mongo_spec.rb +225 -139
- data/spec/mongoid/contextual/text_search_spec.rb +207 -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 +1063 -0
- data/spec/mongoid/{criterion/scoping_spec.rb → criteria/scopable_spec.rb} +31 -31
- data/spec/mongoid/criteria_spec.rb +530 -2207
- 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_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 +3 -3
- 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 +7 -7
- 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/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 +9 -9
- 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 +23 -23
- data/spec/mongoid/fields/standard_spec.rb +12 -12
- data/spec/mongoid/fields_spec.rb +168 -209
- data/spec/mongoid/{finders_spec.rb → findable_spec.rb} +62 -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} +105 -105
- data/spec/mongoid/log_subscriber_spec.rb +74 -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/{matchers → matchable}/ne_spec.rb +3 -3
- 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 +205 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +148 -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 +432 -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} +19 -14
- 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 +36 -16
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +6 -6
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +2 -2
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +3 -3
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +12 -12
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +6 -6
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +9 -9
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +6 -6
- 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 +22 -33
- 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 +11 -24
- data/spec/mongoid/relations/builders_spec.rb +21 -21
- data/spec/mongoid/relations/cascading/delete_spec.rb +7 -7
- data/spec/mongoid/relations/cascading/destroy_spec.rb +2 -2
- data/spec/mongoid/relations/cascading/nullify_spec.rb +2 -2
- data/spec/mongoid/relations/cascading/restrict_spec.rb +3 -3
- 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 +143 -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 +55 -56
- data/spec/mongoid/relations/embedded/many_spec.rb +357 -367
- data/spec/mongoid/relations/embedded/one_spec.rb +98 -139
- data/spec/mongoid/relations/macros_spec.rb +108 -102
- data/spec/mongoid/relations/metadata_spec.rb +147 -241
- 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 +379 -522
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +345 -417
- data/spec/mongoid/relations/referenced/one_spec.rb +148 -263
- 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 +116 -116
- data/spec/mongoid/relations/touchable_spec.rb +296 -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} +74 -126
- data/spec/mongoid/selectable_spec.rb +134 -0
- data/spec/mongoid/{serialization_spec.rb → serializable_spec.rb} +111 -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 +92 -0
- data/spec/mongoid/sessions_spec.rb +288 -177
- data/spec/mongoid/{sharding_spec.rb → shardable_spec.rb} +8 -8
- data/spec/mongoid/state_spec.rb +10 -10
- 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/updated/short_spec.rb +10 -10
- data/spec/mongoid/timestamps/updated_spec.rb +8 -12
- data/spec/mongoid/timestamps_spec.rb +7 -11
- data/spec/mongoid/{hierarchy_spec.rb → traversable_spec.rb} +19 -19
- data/spec/mongoid/{validations → validatable}/associated_spec.rb +18 -18
- data/spec/mongoid/{validations → validatable}/format_spec.rb +6 -6
- data/spec/mongoid/{validations → validatable}/length_spec.rb +7 -7
- data/spec/mongoid/{validations → validatable}/numericality_spec.rb +1 -1
- data/spec/mongoid/{validations → validatable}/presence_spec.rb +31 -38
- data/spec/mongoid/{validations → validatable}/uniqueness_spec.rb +126 -183
- data/spec/mongoid/{validations_spec.rb → validatable_spec.rb} +28 -28
- data/spec/mongoid_spec.rb +8 -8
- data/spec/rails/mongoid_spec.rb +72 -87
- data/spec/spec_helper.rb +19 -17
- metadata +261 -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/criterion/findable.rb +0 -179
- data/lib/mongoid/errors/versioning_not_on_root.rb +0 -23
- data/lib/mongoid/identity_map.rb +0 -163
- data/lib/mongoid/json.rb +0 -16
- data/lib/mongoid/matchers.rb +0 -32
- data/lib/mongoid/matchers/strategies.rb +0 -97
- data/lib/mongoid/multi_parameter_attributes.rb +0 -105
- data/lib/mongoid/nested_attributes.rb +0 -78
- data/lib/mongoid/observer.rb +0 -192
- data/lib/mongoid/paranoia.rb +0 -136
- data/lib/mongoid/persistence.rb +0 -357
- data/lib/mongoid/persistence/atomic.rb +0 -231
- data/lib/mongoid/persistence/atomic/add_to_set.rb +0 -47
- data/lib/mongoid/persistence/atomic/bit.rb +0 -35
- data/lib/mongoid/persistence/atomic/inc.rb +0 -45
- data/lib/mongoid/persistence/atomic/operation.rb +0 -154
- data/lib/mongoid/persistence/atomic/pop.rb +0 -32
- data/lib/mongoid/persistence/atomic/pull.rb +0 -32
- data/lib/mongoid/persistence/atomic/pull_all.rb +0 -32
- data/lib/mongoid/persistence/atomic/push.rb +0 -25
- data/lib/mongoid/persistence/atomic/push_all.rb +0 -25
- data/lib/mongoid/persistence/atomic/rename.rb +0 -30
- data/lib/mongoid/persistence/atomic/sets.rb +0 -28
- data/lib/mongoid/persistence/atomic/unset.rb +0 -27
- data/lib/mongoid/persistence/deletion.rb +0 -31
- data/lib/mongoid/persistence/insertion.rb +0 -38
- data/lib/mongoid/persistence/modification.rb +0 -35
- data/lib/mongoid/persistence/operations.rb +0 -214
- data/lib/mongoid/persistence/operations/embedded/insert.rb +0 -46
- data/lib/mongoid/persistence/operations/embedded/remove.rb +0 -43
- data/lib/mongoid/persistence/operations/insert.rb +0 -34
- data/lib/mongoid/persistence/operations/remove.rb +0 -33
- data/lib/mongoid/persistence/operations/update.rb +0 -59
- data/lib/mongoid/persistence/operations/upsert.rb +0 -28
- data/lib/mongoid/persistence/upsertion.rb +0 -31
- data/lib/mongoid/unit_of_work.rb +0 -61
- data/lib/mongoid/versioning.rb +0 -217
- data/lib/rack/mongoid.rb +0 -2
- data/lib/rack/mongoid/middleware/identity_map.rb +0 -39
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +0 -17
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +0 -4
- data/spec/app/models/actor_observer.rb +0 -15
- data/spec/app/models/callback_recorder.rb +0 -25
- data/spec/app/models/draft.rb +0 -9
- 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/#atomic_spec.rb# +0 -365
- 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/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
data/lib/mongoid/atomic.rb
CHANGED
@@ -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.
|
@@ -22,36 +22,6 @@ module Mongoid
|
|
22
22
|
def path
|
23
23
|
@path ||= position.sub(/\.\d+$/, "")
|
24
24
|
end
|
25
|
-
|
26
|
-
# Get the selector to use for the root document when performing atomic
|
27
|
-
# updates. When sharding this will include the shard key.
|
28
|
-
#
|
29
|
-
# @example Get the selector.
|
30
|
-
# many.selector
|
31
|
-
#
|
32
|
-
# @return [ Hash ] The selector to identify the document with.
|
33
|
-
#
|
34
|
-
# @since 2.1.0
|
35
|
-
def selector
|
36
|
-
@selector ||= generate_selector
|
37
|
-
end
|
38
|
-
|
39
|
-
private
|
40
|
-
|
41
|
-
def generate_selector
|
42
|
-
if only_root_selector?
|
43
|
-
parent.atomic_selector
|
44
|
-
else
|
45
|
-
parent.
|
46
|
-
atomic_selector.
|
47
|
-
merge("#{path}._id" => document._id).
|
48
|
-
merge(document.shard_key_selector)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def only_root_selector?
|
53
|
-
document.persisted? && document._id_changed?
|
54
|
-
end
|
55
25
|
end
|
56
26
|
end
|
57
27
|
end
|
@@ -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/attributes.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "mongoid/attributes/dynamic"
|
3
|
+
require "mongoid/attributes/nested"
|
2
4
|
require "mongoid/attributes/processing"
|
3
5
|
require "mongoid/attributes/readonly"
|
4
6
|
|
@@ -8,6 +10,7 @@ module Mongoid
|
|
8
10
|
# and how to get and set values.
|
9
11
|
module Attributes
|
10
12
|
extend ActiveSupport::Concern
|
13
|
+
include Nested
|
11
14
|
include Processing
|
12
15
|
include Readonly
|
13
16
|
|
@@ -141,25 +144,6 @@ module Mongoid
|
|
141
144
|
end
|
142
145
|
end
|
143
146
|
|
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
147
|
# Write a single attribute to the document attribute hash. This will
|
164
148
|
# also fire the before and after update callbacks, and perform any
|
165
149
|
# necessary typecasting.
|
@@ -178,6 +162,7 @@ module Mongoid
|
|
178
162
|
access = database_field_name(name.to_s)
|
179
163
|
if attribute_writable?(access)
|
180
164
|
_assigning do
|
165
|
+
validate_attribute_value(access, value)
|
181
166
|
localized = fields[access].try(:localized?)
|
182
167
|
attributes_before_type_cast[name.to_s] = value
|
183
168
|
typed_value = typed_value_for(access, value)
|
@@ -207,12 +192,11 @@ module Mongoid
|
|
207
192
|
# person.assign_attributes({ :title => "Mr." }, :as => :admin)
|
208
193
|
#
|
209
194
|
# @param [ Hash ] attrs The new attributes to set.
|
210
|
-
# @param [ Hash ] options Supported options: :without_protection, :as
|
211
195
|
#
|
212
196
|
# @since 2.2.1
|
213
|
-
def assign_attributes(attrs = nil
|
197
|
+
def assign_attributes(attrs = nil)
|
214
198
|
_assigning do
|
215
|
-
process_attributes(attrs
|
199
|
+
process_attributes(attrs)
|
216
200
|
end
|
217
201
|
end
|
218
202
|
|
@@ -230,73 +214,13 @@ module Mongoid
|
|
230
214
|
# @param [ Boolean ] guard_protected_attributes False to skip mass assignment protection.
|
231
215
|
#
|
232
216
|
# @since 1.0.0
|
233
|
-
def write_attributes(attrs = nil
|
234
|
-
assign_attributes(attrs
|
217
|
+
def write_attributes(attrs = nil)
|
218
|
+
assign_attributes(attrs)
|
235
219
|
end
|
236
220
|
alias :attributes= :write_attributes
|
237
221
|
|
238
222
|
private
|
239
223
|
|
240
|
-
# Define a reader method for a dynamic attribute.
|
241
|
-
#
|
242
|
-
# @api private
|
243
|
-
#
|
244
|
-
# @example Define a reader method.
|
245
|
-
# model.define_dynamic_reader(:field)
|
246
|
-
#
|
247
|
-
# @param [ String ] name The name of the field.
|
248
|
-
#
|
249
|
-
# @since 3.0.0
|
250
|
-
def define_dynamic_reader(name)
|
251
|
-
return unless name.valid_method_name?
|
252
|
-
|
253
|
-
class_eval <<-READER
|
254
|
-
def #{name}
|
255
|
-
attribute_will_change!(#{name.inspect})
|
256
|
-
read_attribute(#{name.inspect})
|
257
|
-
end
|
258
|
-
READER
|
259
|
-
end
|
260
|
-
|
261
|
-
# Define a reader method for a dynamic attribute before type cast.
|
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
|
279
|
-
|
280
|
-
# Define a writer method for a dynamic attribute.
|
281
|
-
#
|
282
|
-
# @api private
|
283
|
-
#
|
284
|
-
# @example Define a writer method.
|
285
|
-
# model.define_dynamic_writer(:field)
|
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?
|
292
|
-
|
293
|
-
class_eval <<-WRITER
|
294
|
-
def #{name}=(value)
|
295
|
-
write_attribute(#{name.inspect}, value)
|
296
|
-
end
|
297
|
-
WRITER
|
298
|
-
end
|
299
|
-
|
300
224
|
# Does the string contain dot syntax for accessing hashes?
|
301
225
|
#
|
302
226
|
# @api private
|
@@ -308,30 +232,7 @@ module Mongoid
|
|
308
232
|
#
|
309
233
|
# @since 3.0.15
|
310
234
|
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
|
235
|
+
string =~ /\./
|
335
236
|
end
|
336
237
|
|
337
238
|
# Return the typecasted value for a field.
|
@@ -367,6 +268,7 @@ module Mongoid
|
|
367
268
|
#
|
368
269
|
# @since 2.3.0
|
369
270
|
def alias_attribute(name, original)
|
271
|
+
aliased_fields[name.to_s] = original.to_s
|
370
272
|
class_eval <<-RUBY
|
371
273
|
alias #{name} #{original}
|
372
274
|
alias #{name}= #{original}=
|
@@ -380,5 +282,25 @@ module Mongoid
|
|
380
282
|
RUBY
|
381
283
|
end
|
382
284
|
end
|
285
|
+
|
286
|
+
private
|
287
|
+
|
288
|
+
# Validates an attribute value. This provides validation checking if
|
289
|
+
# the value is valid for given a field.
|
290
|
+
# For now, only Hash and Array fields are validated.
|
291
|
+
#
|
292
|
+
# @param [ String, Symbol ] name The name of the attribute to validate.
|
293
|
+
# @param [ Object ] value The to be validated.
|
294
|
+
#
|
295
|
+
# @since 3.0.10
|
296
|
+
def validate_attribute_value(access, value)
|
297
|
+
return unless fields[access] && value
|
298
|
+
validatable_types = [ Hash, Array ]
|
299
|
+
if validatable_types.include? fields[access].type
|
300
|
+
unless value.is_a? fields[access].type
|
301
|
+
raise Mongoid::Errors::InvalidValue.new(fields[access].type, value.class)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
383
305
|
end
|
384
306
|
end
|
@@ -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
|