mongoid_rails4 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 +7 -0
- data/CHANGELOG.md +3213 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +35 -0
- data/lib/config/locales/en.yml +448 -0
- data/lib/mongoid.rb +104 -0
- data/lib/mongoid/atomic.rb +384 -0
- data/lib/mongoid/atomic/modifiers.rb +317 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +28 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
- data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
- data/lib/mongoid/atomic/paths/root.rb +39 -0
- data/lib/mongoid/attributes.rb +284 -0
- data/lib/mongoid/attributes/dynamic.rb +154 -0
- data/lib/mongoid/attributes/nested.rb +82 -0
- data/lib/mongoid/attributes/processing.rb +147 -0
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/changeable.rb +379 -0
- data/lib/mongoid/composable.rb +104 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/config/environment.rb +44 -0
- data/lib/mongoid/config/options.rb +74 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/contextual.rb +54 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +147 -0
- data/lib/mongoid/contextual/atomic.rb +180 -0
- data/lib/mongoid/contextual/command.rb +61 -0
- data/lib/mongoid/contextual/eager.rb +158 -0
- data/lib/mongoid/contextual/find_and_modify.rb +69 -0
- data/lib/mongoid/contextual/geo_near.rb +238 -0
- data/lib/mongoid/contextual/map_reduce.rb +324 -0
- data/lib/mongoid/contextual/memory.rb +440 -0
- data/lib/mongoid/contextual/mongo.rb +676 -0
- data/lib/mongoid/contextual/queryable.rb +25 -0
- data/lib/mongoid/contextual/text_search.rb +180 -0
- data/lib/mongoid/copyable.rb +67 -0
- data/lib/mongoid/criteria.rb +562 -0
- data/lib/mongoid/criteria/findable.rb +179 -0
- data/lib/mongoid/criteria/inspectable.rb +25 -0
- data/lib/mongoid/criteria/marshalable.rb +50 -0
- data/lib/mongoid/criteria/modifiable.rb +189 -0
- data/lib/mongoid/criteria/scopable.rb +158 -0
- data/lib/mongoid/document.rb +361 -0
- data/lib/mongoid/equality.rb +66 -0
- data/lib/mongoid/errors.rb +40 -0
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +25 -0
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +111 -0
- data/lib/mongoid/errors/eager_load.rb +22 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_field.rb +64 -0
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_includes.rb +32 -0
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_path.rb +21 -0
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +22 -0
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +32 -0
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +92 -0
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +19 -0
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_metadata.rb +21 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +21 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +19 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/validations.rb +29 -0
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions.rb +35 -0
- data/lib/mongoid/extensions/array.rb +180 -0
- data/lib/mongoid/extensions/big_decimal.rb +69 -0
- data/lib/mongoid/extensions/boolean.rb +21 -0
- data/lib/mongoid/extensions/date.rb +77 -0
- data/lib/mongoid/extensions/date_time.rb +73 -0
- data/lib/mongoid/extensions/false_class.rb +38 -0
- data/lib/mongoid/extensions/float.rb +56 -0
- data/lib/mongoid/extensions/hash.rb +209 -0
- data/lib/mongoid/extensions/integer.rb +67 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +33 -0
- data/lib/mongoid/extensions/object.rb +274 -0
- data/lib/mongoid/extensions/object_id.rb +54 -0
- data/lib/mongoid/extensions/range.rb +79 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +199 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +88 -0
- data/lib/mongoid/extensions/time_with_zone.rb +56 -0
- data/lib/mongoid/extensions/true_class.rb +38 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +542 -0
- data/lib/mongoid/fields/foreign_key.rb +174 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +273 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields/validators/macro.rb +92 -0
- data/lib/mongoid/findable.rb +133 -0
- data/lib/mongoid/identity_map.rb +163 -0
- data/lib/mongoid/indexable.rb +147 -0
- data/lib/mongoid/indexable/specification.rb +115 -0
- data/lib/mongoid/indexable/validators/options.rb +103 -0
- data/lib/mongoid/inspectable.rb +59 -0
- data/lib/mongoid/interceptable.rb +265 -0
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchable.rb +152 -0
- data/lib/mongoid/matchable/all.rb +27 -0
- data/lib/mongoid/matchable/and.rb +30 -0
- data/lib/mongoid/matchable/default.rb +72 -0
- data/lib/mongoid/matchable/exists.rb +23 -0
- data/lib/mongoid/matchable/gt.rb +21 -0
- data/lib/mongoid/matchable/gte.rb +21 -0
- data/lib/mongoid/matchable/in.rb +24 -0
- data/lib/mongoid/matchable/lt.rb +21 -0
- data/lib/mongoid/matchable/lte.rb +21 -0
- data/lib/mongoid/matchable/ne.rb +21 -0
- data/lib/mongoid/matchable/nin.rb +21 -0
- data/lib/mongoid/matchable/or.rb +33 -0
- data/lib/mongoid/matchable/size.rb +21 -0
- data/lib/mongoid/persistable.rb +207 -0
- data/lib/mongoid/persistable/creatable.rb +189 -0
- data/lib/mongoid/persistable/deletable.rb +149 -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 +156 -0
- data/lib/mongoid/railties/database.rake +97 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +162 -0
- data/lib/mongoid/relations/accessors.rb +299 -0
- data/lib/mongoid/relations/auto_save.rb +106 -0
- data/lib/mongoid/relations/binding.rb +218 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +104 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +56 -0
- data/lib/mongoid/relations/cascading/delete.rb +44 -0
- data/lib/mongoid/relations/cascading/destroy.rb +43 -0
- data/lib/mongoid/relations/cascading/nullify.rb +35 -0
- data/lib/mongoid/relations/cascading/restrict.rb +39 -0
- data/lib/mongoid/relations/constraint.rb +49 -0
- data/lib/mongoid/relations/conversions.rb +34 -0
- data/lib/mongoid/relations/counter_cache.rb +105 -0
- data/lib/mongoid/relations/cyclic.rb +107 -0
- data/lib/mongoid/relations/embedded/batchable.rb +355 -0
- data/lib/mongoid/relations/embedded/in.rb +231 -0
- data/lib/mongoid/relations/embedded/many.rb +639 -0
- data/lib/mongoid/relations/embedded/one.rb +223 -0
- data/lib/mongoid/relations/macros.rb +356 -0
- data/lib/mongoid/relations/many.rb +208 -0
- data/lib/mongoid/relations/marshalable.rb +32 -0
- data/lib/mongoid/relations/metadata.rb +1174 -0
- data/lib/mongoid/relations/nested_builder.rb +74 -0
- data/lib/mongoid/relations/one.rb +48 -0
- data/lib/mongoid/relations/options.rb +48 -0
- data/lib/mongoid/relations/polymorphic.rb +39 -0
- data/lib/mongoid/relations/proxy.rb +270 -0
- data/lib/mongoid/relations/referenced/in.rb +297 -0
- data/lib/mongoid/relations/referenced/many.rb +787 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
- data/lib/mongoid/relations/referenced/one.rb +290 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +169 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +473 -0
- data/lib/mongoid/relations/touchable.rb +94 -0
- data/lib/mongoid/reloadable.rb +95 -0
- data/lib/mongoid/scopable.rb +379 -0
- data/lib/mongoid/selectable.rb +59 -0
- data/lib/mongoid/serializable.rb +170 -0
- data/lib/mongoid/sessions.rb +330 -0
- data/lib/mongoid/sessions/factory.rb +129 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/options.rb +141 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/shardable.rb +65 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +383 -0
- data/lib/mongoid/threaded/lifecycle.rb +164 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +30 -0
- data/lib/mongoid/timestamps/created/short.rb +19 -0
- data/lib/mongoid/timestamps/short.rb +10 -0
- data/lib/mongoid/timestamps/updated.rb +39 -0
- data/lib/mongoid/timestamps/updated/short.rb +19 -0
- data/lib/mongoid/traversable.rb +192 -0
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validatable.rb +180 -0
- data/lib/mongoid/validatable/associated.rb +48 -0
- data/lib/mongoid/validatable/format.rb +20 -0
- data/lib/mongoid/validatable/length.rb +20 -0
- data/lib/mongoid/validatable/localizable.rb +30 -0
- data/lib/mongoid/validatable/macros.rb +94 -0
- data/lib/mongoid/validatable/presence.rb +86 -0
- data/lib/mongoid/validatable/queryable.rb +30 -0
- data/lib/mongoid/validatable/uniqueness.rb +330 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
- data/lib/rails/generators/mongoid_generator.rb +65 -0
- data/lib/rails/mongoid.rb +180 -0
- data/lib/support/ruby_version.rb +26 -0
- data/spec/app/models/account.rb +28 -0
- data/spec/app/models/acolyte.rb +17 -0
- data/spec/app/models/actor.rb +18 -0
- data/spec/app/models/actress.rb +2 -0
- data/spec/app/models/address.rb +77 -0
- data/spec/app/models/address_component.rb +5 -0
- data/spec/app/models/address_number.rb +6 -0
- data/spec/app/models/agency.rb +5 -0
- data/spec/app/models/agent.rb +12 -0
- data/spec/app/models/album.rb +14 -0
- data/spec/app/models/alert.rb +5 -0
- data/spec/app/models/animal.rb +25 -0
- data/spec/app/models/answer.rb +4 -0
- data/spec/app/models/appointment.rb +7 -0
- data/spec/app/models/article.rb +10 -0
- data/spec/app/models/artist.rb +66 -0
- data/spec/app/models/artwork.rb +4 -0
- data/spec/app/models/audio.rb +5 -0
- data/spec/app/models/augmentation.rb +11 -0
- data/spec/app/models/author.rb +4 -0
- data/spec/app/models/band.rb +26 -0
- data/spec/app/models/bar.rb +10 -0
- data/spec/app/models/basic.rb +6 -0
- data/spec/app/models/bed.rb +1 -0
- data/spec/app/models/big_palette.rb +2 -0
- data/spec/app/models/birthday.rb +13 -0
- data/spec/app/models/book.rb +13 -0
- data/spec/app/models/breed.rb +4 -0
- data/spec/app/models/browser.rb +6 -0
- data/spec/app/models/building.rb +5 -0
- data/spec/app/models/building_address.rb +5 -0
- data/spec/app/models/bus.rb +7 -0
- data/spec/app/models/business.rb +5 -0
- data/spec/app/models/callback_recorder.rb +25 -0
- data/spec/app/models/callback_test.rb +9 -0
- data/spec/app/models/canvas.rb +25 -0
- data/spec/app/models/car.rb +1 -0
- data/spec/app/models/cat.rb +8 -0
- data/spec/app/models/category.rb +8 -0
- data/spec/app/models/child.rb +4 -0
- data/spec/app/models/child_doc.rb +22 -0
- data/spec/app/models/church.rb +4 -0
- data/spec/app/models/circle.rb +3 -0
- data/spec/app/models/circuit.rb +4 -0
- data/spec/app/models/circus.rb +7 -0
- data/spec/app/models/code.rb +5 -0
- data/spec/app/models/comment.rb +16 -0
- data/spec/app/models/contractor.rb +5 -0
- data/spec/app/models/cookie.rb +6 -0
- data/spec/app/models/country_code.rb +8 -0
- data/spec/app/models/definition.rb +7 -0
- data/spec/app/models/description.rb +11 -0
- data/spec/app/models/dictionary.rb +10 -0
- data/spec/app/models/division.rb +10 -0
- data/spec/app/models/doctor.rb +12 -0
- data/spec/app/models/dog.rb +7 -0
- data/spec/app/models/dokument.rb +5 -0
- data/spec/app/models/dragon.rb +4 -0
- data/spec/app/models/driver.rb +7 -0
- data/spec/app/models/drug.rb +6 -0
- data/spec/app/models/dungeon.rb +4 -0
- data/spec/app/models/email.rb +6 -0
- data/spec/app/models/employer.rb +5 -0
- data/spec/app/models/entry.rb +6 -0
- data/spec/app/models/eraser.rb +1 -0
- data/spec/app/models/event.rb +22 -0
- data/spec/app/models/exhibition.rb +4 -0
- data/spec/app/models/exhibitor.rb +5 -0
- data/spec/app/models/eye.rb +9 -0
- data/spec/app/models/eye_bowl.rb +9 -0
- data/spec/app/models/face.rb +8 -0
- data/spec/app/models/favorite.rb +6 -0
- data/spec/app/models/filesystem.rb +5 -0
- data/spec/app/models/fire_hydrant.rb +6 -0
- data/spec/app/models/firefox.rb +4 -0
- data/spec/app/models/fish.rb +7 -0
- data/spec/app/models/folder.rb +7 -0
- data/spec/app/models/folder_item.rb +9 -0
- data/spec/app/models/fruits.rb +28 -0
- data/spec/app/models/game.rb +19 -0
- data/spec/app/models/ghost.rb +7 -0
- data/spec/app/models/home.rb +4 -0
- data/spec/app/models/house.rb +6 -0
- data/spec/app/models/html_writer.rb +3 -0
- data/spec/app/models/image.rb +22 -0
- data/spec/app/models/implant.rb +16 -0
- data/spec/app/models/item.rb +8 -0
- data/spec/app/models/jar.rb +7 -0
- data/spec/app/models/label.rb +40 -0
- data/spec/app/models/language.rb +5 -0
- data/spec/app/models/lat_lng.rb +15 -0
- data/spec/app/models/league.rb +11 -0
- data/spec/app/models/learner.rb +2 -0
- data/spec/app/models/line_item.rb +6 -0
- data/spec/app/models/location.rb +8 -0
- data/spec/app/models/login.rb +8 -0
- data/spec/app/models/manufacturer.rb +7 -0
- data/spec/app/models/meat.rb +4 -0
- data/spec/app/models/membership.rb +4 -0
- data/spec/app/models/mixed_drink.rb +4 -0
- data/spec/app/models/movie.rb +13 -0
- data/spec/app/models/my_hash.rb +2 -0
- data/spec/app/models/name.rb +23 -0
- data/spec/app/models/node.rb +5 -0
- data/spec/app/models/note.rb +12 -0
- data/spec/app/models/ordered_post.rb +6 -0
- data/spec/app/models/ordered_preference.rb +6 -0
- data/spec/app/models/oscar.rb +15 -0
- data/spec/app/models/override.rb +16 -0
- data/spec/app/models/ownable.rb +6 -0
- data/spec/app/models/owner.rb +6 -0
- data/spec/app/models/pack.rb +3 -0
- data/spec/app/models/page.rb +5 -0
- data/spec/app/models/page_question.rb +4 -0
- data/spec/app/models/palette.rb +7 -0
- data/spec/app/models/parent.rb +5 -0
- data/spec/app/models/parent_doc.rb +6 -0
- data/spec/app/models/passport.rb +5 -0
- data/spec/app/models/patient.rb +9 -0
- data/spec/app/models/pdf_writer.rb +3 -0
- data/spec/app/models/pencil.rb +1 -0
- data/spec/app/models/person.rb +205 -0
- data/spec/app/models/pet.rb +23 -0
- data/spec/app/models/pet_owner.rb +6 -0
- data/spec/app/models/phone.rb +11 -0
- data/spec/app/models/pizza.rb +7 -0
- data/spec/app/models/player.rb +35 -0
- data/spec/app/models/post.rb +44 -0
- data/spec/app/models/powerup.rb +11 -0
- data/spec/app/models/preference.rb +9 -0
- data/spec/app/models/princess.rb +8 -0
- data/spec/app/models/product.rb +15 -0
- data/spec/app/models/profile.rb +5 -0
- data/spec/app/models/pronunciation.rb +5 -0
- data/spec/app/models/purchase.rb +4 -0
- data/spec/app/models/question.rb +8 -0
- data/spec/app/models/quiz.rb +7 -0
- data/spec/app/models/rating.rb +8 -0
- data/spec/app/models/record.rb +46 -0
- data/spec/app/models/registry.rb +4 -0
- data/spec/app/models/role.rb +7 -0
- data/spec/app/models/root_category.rb +4 -0
- data/spec/app/models/sandwich.rb +4 -0
- data/spec/app/models/scheduler.rb +7 -0
- data/spec/app/models/seo.rb +7 -0
- data/spec/app/models/series.rb +4 -0
- data/spec/app/models/server.rb +13 -0
- data/spec/app/models/service.rb +22 -0
- data/spec/app/models/shape.rb +12 -0
- data/spec/app/models/shelf.rb +5 -0
- data/spec/app/models/shipping_container.rb +5 -0
- data/spec/app/models/shipping_pack.rb +3 -0
- data/spec/app/models/shop.rb +6 -0
- data/spec/app/models/short_agent.rb +4 -0
- data/spec/app/models/short_quiz.rb +5 -0
- data/spec/app/models/slave.rb +6 -0
- data/spec/app/models/song.rb +8 -0
- data/spec/app/models/sound.rb +5 -0
- data/spec/app/models/square.rb +4 -0
- data/spec/app/models/strategy.rb +3 -0
- data/spec/app/models/sub_item.rb +3 -0
- data/spec/app/models/subscription.rb +4 -0
- data/spec/app/models/survey.rb +5 -0
- data/spec/app/models/symptom.rb +6 -0
- data/spec/app/models/tag.rb +8 -0
- data/spec/app/models/target.rb +5 -0
- data/spec/app/models/template.rb +5 -0
- data/spec/app/models/thing.rb +9 -0
- data/spec/app/models/title.rb +3 -0
- data/spec/app/models/tool.rb +8 -0
- data/spec/app/models/topping.rb +5 -0
- data/spec/app/models/track.rb +38 -0
- data/spec/app/models/translation.rb +5 -0
- data/spec/app/models/tree.rb +9 -0
- data/spec/app/models/truck.rb +3 -0
- data/spec/app/models/user.rb +21 -0
- data/spec/app/models/user_account.rb +10 -0
- data/spec/app/models/validation_callback.rb +10 -0
- data/spec/app/models/vehicle.rb +11 -0
- data/spec/app/models/version.rb +5 -0
- data/spec/app/models/vet_visit.rb +5 -0
- data/spec/app/models/video.rb +13 -0
- data/spec/app/models/weapon.rb +11 -0
- data/spec/app/models/wiki_page.rb +14 -0
- data/spec/app/models/word.rb +15 -0
- data/spec/app/models/word_origin.rb +11 -0
- data/spec/app/models/writer.rb +11 -0
- data/spec/config/mongoid.yml +38 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
- data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
- data/spec/mongoid/atomic/paths_spec.rb +270 -0
- data/spec/mongoid/atomic_spec.rb +365 -0
- data/spec/mongoid/attributes/nested_spec.rb +4832 -0
- data/spec/mongoid/attributes/readonly_spec.rb +169 -0
- data/spec/mongoid/attributes_spec.rb +1412 -0
- data/spec/mongoid/changeable_spec.rb +1507 -0
- data/spec/mongoid/composable_spec.rb +24 -0
- data/spec/mongoid/config/environment_spec.rb +83 -0
- data/spec/mongoid/config/options_spec.rb +56 -0
- data/spec/mongoid/config_spec.rb +318 -0
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
- data/spec/mongoid/contextual/atomic_spec.rb +529 -0
- data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
- data/spec/mongoid/contextual/memory_spec.rb +1236 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
- data/spec/mongoid/contextual/text_search_spec.rb +207 -0
- data/spec/mongoid/copyable_spec.rb +393 -0
- data/spec/mongoid/criteria/findable_spec.rb +1189 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
- data/spec/mongoid/criteria/scopable_spec.rb +391 -0
- data/spec/mongoid/criteria_spec.rb +3821 -0
- data/spec/mongoid/document_spec.rb +1205 -0
- data/spec/mongoid/equality_spec.rb +241 -0
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
- data/spec/mongoid/errors/callback_spec.rb +29 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
- data/spec/mongoid/errors/eager_load_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
- data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
- data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
- data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
- data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/no_environment_spec.rb +29 -0
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
- data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
- data/spec/mongoid/errors/no_parent_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
- data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
- data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
- data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
- data/spec/mongoid/errors/validations_spec.rb +45 -0
- data/spec/mongoid/extensions/array_spec.rb +638 -0
- data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
- data/spec/mongoid/extensions/binary_spec.rb +60 -0
- data/spec/mongoid/extensions/boolean_spec.rb +135 -0
- data/spec/mongoid/extensions/date_spec.rb +235 -0
- data/spec/mongoid/extensions/date_time_spec.rb +155 -0
- data/spec/mongoid/extensions/false_class_spec.rb +42 -0
- data/spec/mongoid/extensions/float_spec.rb +133 -0
- data/spec/mongoid/extensions/hash_spec.rb +333 -0
- data/spec/mongoid/extensions/integer_spec.rb +136 -0
- data/spec/mongoid/extensions/module_spec.rb +42 -0
- data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
- data/spec/mongoid/extensions/object_id_spec.rb +946 -0
- data/spec/mongoid/extensions/object_spec.rb +292 -0
- data/spec/mongoid/extensions/range_spec.rb +105 -0
- data/spec/mongoid/extensions/regexp_spec.rb +47 -0
- data/spec/mongoid/extensions/set_spec.rb +33 -0
- data/spec/mongoid/extensions/string_spec.rb +357 -0
- data/spec/mongoid/extensions/symbol_spec.rb +76 -0
- data/spec/mongoid/extensions/time_spec.rb +467 -0
- data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
- data/spec/mongoid/extensions/true_class_spec.rb +42 -0
- data/spec/mongoid/extensions_spec.rb +15 -0
- data/spec/mongoid/factory_spec.rb +185 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
- data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
- data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
- data/spec/mongoid/fields/localized_spec.rb +386 -0
- data/spec/mongoid/fields/standard_spec.rb +166 -0
- data/spec/mongoid/fields_spec.rb +1229 -0
- data/spec/mongoid/findable_spec.rb +342 -0
- data/spec/mongoid/identity_map_spec.rb +564 -0
- data/spec/mongoid/indexable/specification_spec.rb +87 -0
- data/spec/mongoid/indexable_spec.rb +504 -0
- data/spec/mongoid/inspectable_spec.rb +49 -0
- data/spec/mongoid/interceptable_spec.rb +1564 -0
- data/spec/mongoid/loggable_spec.rb +21 -0
- data/spec/mongoid/matchable/all_spec.rb +31 -0
- data/spec/mongoid/matchable/and_spec.rb +162 -0
- data/spec/mongoid/matchable/default_spec.rb +130 -0
- data/spec/mongoid/matchable/exists_spec.rb +57 -0
- data/spec/mongoid/matchable/gt_spec.rb +75 -0
- data/spec/mongoid/matchable/gte_spec.rb +74 -0
- data/spec/mongoid/matchable/in_spec.rb +25 -0
- data/spec/mongoid/matchable/lt_spec.rb +74 -0
- data/spec/mongoid/matchable/lte_spec.rb +74 -0
- data/spec/mongoid/matchable/ne_spec.rb +25 -0
- data/spec/mongoid/matchable/nin_spec.rb +25 -0
- data/spec/mongoid/matchable/or_spec.rb +106 -0
- data/spec/mongoid/matchable/size_spec.rb +25 -0
- data/spec/mongoid/matchable_spec.rb +532 -0
- 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 +522 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
- data/spec/mongoid/persistable_spec.rb +206 -0
- data/spec/mongoid/positional_spec.rb +227 -0
- data/spec/mongoid/railties/document_spec.rb +24 -0
- data/spec/mongoid/relations/accessors_spec.rb +736 -0
- data/spec/mongoid/relations/auto_save_spec.rb +261 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
- data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
- data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
- data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
- data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
- data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
- data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
- data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
- data/spec/mongoid/relations/builders_spec.rb +226 -0
- data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
- data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
- data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
- data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
- data/spec/mongoid/relations/cascading_spec.rb +355 -0
- data/spec/mongoid/relations/constraint_spec.rb +74 -0
- data/spec/mongoid/relations/conversions_spec.rb +126 -0
- data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
- data/spec/mongoid/relations/cyclic_spec.rb +156 -0
- data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
- data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
- data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
- data/spec/mongoid/relations/macros_spec.rb +613 -0
- data/spec/mongoid/relations/metadata_spec.rb +1917 -0
- data/spec/mongoid/relations/options_spec.rb +35 -0
- data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
- data/spec/mongoid/relations/proxy_spec.rb +48 -0
- data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
- data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
- data/spec/mongoid/relations/reflections_spec.rb +101 -0
- data/spec/mongoid/relations/synchronization_spec.rb +449 -0
- data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
- data/spec/mongoid/relations/touchable_spec.rb +296 -0
- data/spec/mongoid/relations_spec.rb +188 -0
- data/spec/mongoid/reloadable_spec.rb +305 -0
- data/spec/mongoid/scopable_spec.rb +926 -0
- data/spec/mongoid/selectable_spec.rb +134 -0
- data/spec/mongoid/serializable_spec.rb +862 -0
- data/spec/mongoid/sessions/factory_spec.rb +312 -0
- data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
- data/spec/mongoid/sessions/options_spec.rb +71 -0
- data/spec/mongoid/sessions_spec.rb +1078 -0
- data/spec/mongoid/shardable_spec.rb +61 -0
- data/spec/mongoid/state_spec.rb +102 -0
- data/spec/mongoid/threaded_spec.rb +258 -0
- data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
- data/spec/mongoid/timestamps/created_spec.rb +44 -0
- data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
- data/spec/mongoid/timestamps/updated_spec.rb +86 -0
- data/spec/mongoid/timestamps_spec.rb +112 -0
- data/spec/mongoid/traversable_spec.rb +244 -0
- data/spec/mongoid/unit_of_work_spec.rb +196 -0
- data/spec/mongoid/validatable/associated_spec.rb +183 -0
- data/spec/mongoid/validatable/format_spec.rb +83 -0
- data/spec/mongoid/validatable/length_spec.rb +119 -0
- data/spec/mongoid/validatable/numericality_spec.rb +30 -0
- data/spec/mongoid/validatable/presence_spec.rb +511 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
- data/spec/mongoid/validatable_spec.rb +309 -0
- data/spec/mongoid_spec.rb +74 -0
- data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
- data/spec/rails/mongoid_spec.rb +462 -0
- data/spec/spec_helper.rb +103 -0
- metadata +1159 -0
@@ -0,0 +1,169 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Attributes::Readonly do
|
4
|
+
|
5
|
+
describe ".attr_readonly" do
|
6
|
+
|
7
|
+
after do
|
8
|
+
Person.readonly_attributes.clear
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when providing a single field" do
|
12
|
+
|
13
|
+
before do
|
14
|
+
Person.attr_readonly :title
|
15
|
+
end
|
16
|
+
|
17
|
+
it "adds the field to readonly attributes" do
|
18
|
+
expect(Person.readonly_attributes.to_a).to eq([ "title" ])
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when providing multiple fields" do
|
23
|
+
|
24
|
+
before do
|
25
|
+
Person.attr_readonly :title, :terms
|
26
|
+
end
|
27
|
+
|
28
|
+
it "adds the fields to readonly attributes" do
|
29
|
+
expect(Person.readonly_attributes.to_a).to eq([ "title", "terms" ])
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when creating a new document with a readonly field" do
|
34
|
+
|
35
|
+
before do
|
36
|
+
Person.attr_readonly :title, :terms
|
37
|
+
end
|
38
|
+
|
39
|
+
let(:person) do
|
40
|
+
Person.create(title: "sir", terms: true)
|
41
|
+
end
|
42
|
+
|
43
|
+
it "sets the first readonly value" do
|
44
|
+
expect(person.title).to eq("sir")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "sets subsequent readonly values" do
|
48
|
+
expect(person.terms).to be_true
|
49
|
+
end
|
50
|
+
|
51
|
+
it "persists the first readonly value" do
|
52
|
+
expect(person.reload.title).to eq("sir")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "persists subsequent readonly values" do
|
56
|
+
expect(person.reload.terms).to be_true
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "when updating an existing readonly field" do
|
61
|
+
|
62
|
+
before do
|
63
|
+
Person.attr_readonly :title, :terms
|
64
|
+
end
|
65
|
+
|
66
|
+
let(:person) do
|
67
|
+
Person.create(title: "sir", terms: true)
|
68
|
+
end
|
69
|
+
|
70
|
+
context "when updating via the setter" do
|
71
|
+
|
72
|
+
before do
|
73
|
+
person.title = "mr"
|
74
|
+
person.save
|
75
|
+
end
|
76
|
+
|
77
|
+
it "does not update the field" do
|
78
|
+
expect(person.title).to eq("sir")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "does not persist the changes" do
|
82
|
+
expect(person.reload.title).to eq("sir")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when updating via []=" do
|
87
|
+
|
88
|
+
before do
|
89
|
+
person[:title] = "mr"
|
90
|
+
person.save
|
91
|
+
end
|
92
|
+
|
93
|
+
it "does not update the field" do
|
94
|
+
expect(person.title).to eq("sir")
|
95
|
+
end
|
96
|
+
|
97
|
+
it "does not persist the changes" do
|
98
|
+
expect(person.reload.title).to eq("sir")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when updating via write_attribute" do
|
103
|
+
|
104
|
+
before do
|
105
|
+
person.write_attribute(:title, "mr")
|
106
|
+
person.save
|
107
|
+
end
|
108
|
+
|
109
|
+
it "does not update the field" do
|
110
|
+
expect(person.title).to eq("sir")
|
111
|
+
end
|
112
|
+
|
113
|
+
it "does not persist the changes" do
|
114
|
+
expect(person.reload.title).to eq("sir")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when updating via update_attributes" do
|
119
|
+
|
120
|
+
before do
|
121
|
+
person.update_attributes(title: "mr")
|
122
|
+
person.save
|
123
|
+
end
|
124
|
+
|
125
|
+
it "does not update the field" do
|
126
|
+
expect(person.title).to eq("sir")
|
127
|
+
end
|
128
|
+
|
129
|
+
it "does not persist the changes" do
|
130
|
+
expect(person.reload.title).to eq("sir")
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
context "when updating via update_attributes!" do
|
135
|
+
|
136
|
+
before do
|
137
|
+
person.update_attributes!(title: "mr")
|
138
|
+
person.save
|
139
|
+
end
|
140
|
+
|
141
|
+
it "does not update the field" do
|
142
|
+
expect(person.title).to eq("sir")
|
143
|
+
end
|
144
|
+
|
145
|
+
it "does not persist the changes" do
|
146
|
+
expect(person.reload.title).to eq("sir")
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
context "when updating via update_attribute" do
|
151
|
+
|
152
|
+
it "raises an error" do
|
153
|
+
expect {
|
154
|
+
person.update_attribute(:title, "mr")
|
155
|
+
}.to raise_error(Mongoid::Errors::ReadonlyAttribute)
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
context "when updating via remove_attribute" do
|
160
|
+
|
161
|
+
it "raises an error" do
|
162
|
+
expect {
|
163
|
+
person.remove_attribute(:title)
|
164
|
+
}.to raise_error(Mongoid::Errors::ReadonlyAttribute)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,1412 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Attributes do
|
4
|
+
|
5
|
+
describe "\#{attribute}" do
|
6
|
+
|
7
|
+
context "when setting the value in the getter" do
|
8
|
+
|
9
|
+
let(:account) do
|
10
|
+
Account.new
|
11
|
+
end
|
12
|
+
|
13
|
+
it "does not cause an infinite loop" do
|
14
|
+
expect(account.overridden).to eq("not recommended")
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "#[]" do
|
20
|
+
|
21
|
+
context "when the document is a new record" do
|
22
|
+
|
23
|
+
let(:person) do
|
24
|
+
Person.new
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when accessing a localized field" do
|
28
|
+
|
29
|
+
before do
|
30
|
+
person.desc = "testing"
|
31
|
+
end
|
32
|
+
|
33
|
+
context "when passing just the name" do
|
34
|
+
|
35
|
+
it "returns the full value" do
|
36
|
+
expect(person[:desc]).to eq("en" => "testing")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context "when passing the name with locale" do
|
41
|
+
|
42
|
+
it "returns the value for the locale" do
|
43
|
+
expect(person["desc.en"]).to eq("testing")
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
context "when attribute does not exist" do
|
49
|
+
|
50
|
+
it "returns the default value" do
|
51
|
+
expect(person[:age]).to eq(100)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when attribute is not accessible" do
|
56
|
+
|
57
|
+
before do
|
58
|
+
person.owner_id = 5
|
59
|
+
end
|
60
|
+
|
61
|
+
it "returns the value" do
|
62
|
+
expect(person[:owner_id]).to eq(5)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when the document is an existing record" do
|
68
|
+
|
69
|
+
let!(:person) do
|
70
|
+
Person.create(title: "sir")
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when the attribute does not exist" do
|
74
|
+
|
75
|
+
before do
|
76
|
+
person.collection
|
77
|
+
.find({ _id: person.id })
|
78
|
+
.update({ "$unset" => { age: 1 }})
|
79
|
+
end
|
80
|
+
|
81
|
+
context "when found" do
|
82
|
+
|
83
|
+
let(:found) do
|
84
|
+
Person.find(person.id)
|
85
|
+
end
|
86
|
+
|
87
|
+
it "returns the default value" do
|
88
|
+
expect(found[:age]).to eq(100)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
context "when reloaded" do
|
93
|
+
|
94
|
+
before do
|
95
|
+
Mongoid.raise_not_found_error = false
|
96
|
+
person.reload
|
97
|
+
Mongoid.raise_not_found_error = true
|
98
|
+
end
|
99
|
+
|
100
|
+
it "returns the default value" do
|
101
|
+
expect(person[:age]).to eq(100)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "#[]=" do
|
109
|
+
|
110
|
+
let(:person) do
|
111
|
+
Person.new
|
112
|
+
end
|
113
|
+
|
114
|
+
context "when setting the attribute to nil" do
|
115
|
+
|
116
|
+
let!(:age) do
|
117
|
+
person[:age] = nil
|
118
|
+
end
|
119
|
+
|
120
|
+
it "does not use the default value" do
|
121
|
+
expect(person.age).to be_nil
|
122
|
+
end
|
123
|
+
|
124
|
+
it "returns the set value" do
|
125
|
+
expect(age).to be_nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "when field has a default value" do
|
130
|
+
|
131
|
+
let!(:terms) do
|
132
|
+
person[:terms] = true
|
133
|
+
end
|
134
|
+
|
135
|
+
it "allows overwriting of the default value" do
|
136
|
+
expect(person.terms).to be_true
|
137
|
+
end
|
138
|
+
|
139
|
+
it "returns the set value" do
|
140
|
+
expect(terms).to eq(true)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "#_id" do
|
146
|
+
|
147
|
+
let(:person) do
|
148
|
+
Person.new
|
149
|
+
end
|
150
|
+
|
151
|
+
it "delegates to #id" do
|
152
|
+
expect(person._id).to eq(person.id)
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "#_id=" do
|
157
|
+
|
158
|
+
after(:all) do
|
159
|
+
Person.field(
|
160
|
+
:_id,
|
161
|
+
type: Moped::BSON::ObjectId,
|
162
|
+
pre_processed: true,
|
163
|
+
default: ->{ Moped::BSON::ObjectId.new }
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
167
|
+
context "when using object ids" do
|
168
|
+
|
169
|
+
before(:all) do
|
170
|
+
Person.field(
|
171
|
+
:_id,
|
172
|
+
type: Moped::BSON::ObjectId,
|
173
|
+
pre_processed: true,
|
174
|
+
default: ->{ Moped::BSON::ObjectId.new }
|
175
|
+
)
|
176
|
+
end
|
177
|
+
|
178
|
+
let(:person) do
|
179
|
+
Person.new
|
180
|
+
end
|
181
|
+
|
182
|
+
let(:bson_id) do
|
183
|
+
Moped::BSON::ObjectId.new
|
184
|
+
end
|
185
|
+
|
186
|
+
context "when providing an object id" do
|
187
|
+
|
188
|
+
before do
|
189
|
+
person._id = bson_id
|
190
|
+
end
|
191
|
+
|
192
|
+
it "sets the id as the object id" do
|
193
|
+
expect(person.id).to eq(bson_id)
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
197
|
+
context "when providing a string" do
|
198
|
+
|
199
|
+
before do
|
200
|
+
person._id = bson_id.to_s
|
201
|
+
end
|
202
|
+
|
203
|
+
it "sets the id as the object id" do
|
204
|
+
expect(person.id).to eq(bson_id)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when providing an integer" do
|
209
|
+
|
210
|
+
before do
|
211
|
+
person._id = 2
|
212
|
+
end
|
213
|
+
|
214
|
+
it "sets the id as the supplied value to_s" do
|
215
|
+
expect(person.id).to eq(2)
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "when using string ids" do
|
221
|
+
|
222
|
+
before(:all) do
|
223
|
+
Person.field(
|
224
|
+
:_id,
|
225
|
+
type: String,
|
226
|
+
pre_processed: true,
|
227
|
+
default: ->{ Moped::BSON::ObjectId.new.to_s }
|
228
|
+
)
|
229
|
+
end
|
230
|
+
|
231
|
+
let(:person) do
|
232
|
+
Person.new
|
233
|
+
end
|
234
|
+
|
235
|
+
let(:bson_id) do
|
236
|
+
Moped::BSON::ObjectId.new
|
237
|
+
end
|
238
|
+
|
239
|
+
context "when providing an object id" do
|
240
|
+
|
241
|
+
before do
|
242
|
+
person._id = bson_id
|
243
|
+
end
|
244
|
+
|
245
|
+
it "sets the id as the string of the object id" do
|
246
|
+
expect(person.id).to eq(bson_id.to_s)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
context "when providing a string" do
|
251
|
+
|
252
|
+
before do
|
253
|
+
person._id = bson_id.to_s
|
254
|
+
end
|
255
|
+
|
256
|
+
it "sets the id as the string" do
|
257
|
+
expect(person.id).to eq(bson_id.to_s)
|
258
|
+
end
|
259
|
+
end
|
260
|
+
|
261
|
+
context "when providing an integer" do
|
262
|
+
|
263
|
+
before do
|
264
|
+
person._id = 2
|
265
|
+
end
|
266
|
+
|
267
|
+
it "sets the id as the supplied value to_s" do
|
268
|
+
expect(person.id).to eq("2")
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
context "when using integer ids" do
|
274
|
+
|
275
|
+
before(:all) do
|
276
|
+
Person.field(:_id, type: Integer)
|
277
|
+
end
|
278
|
+
|
279
|
+
let(:person) do
|
280
|
+
Person.new
|
281
|
+
end
|
282
|
+
|
283
|
+
context "when providing a string" do
|
284
|
+
|
285
|
+
before do
|
286
|
+
person._id = 1.to_s
|
287
|
+
end
|
288
|
+
|
289
|
+
it "sets the id as the integer" do
|
290
|
+
expect(person.id).to eq(1)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
|
294
|
+
context "when providing an integer" do
|
295
|
+
|
296
|
+
before do
|
297
|
+
person._id = 2
|
298
|
+
end
|
299
|
+
|
300
|
+
it "sets the id as the supplied value" do
|
301
|
+
expect(person.id).to eq(2)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "#method_missing" do
|
308
|
+
|
309
|
+
let(:attributes) do
|
310
|
+
{ testing: "Testing" }
|
311
|
+
end
|
312
|
+
|
313
|
+
let(:person) do
|
314
|
+
Person.new(attributes)
|
315
|
+
end
|
316
|
+
|
317
|
+
context "when an attribute exists" do
|
318
|
+
|
319
|
+
it "allows the getter" do
|
320
|
+
expect(person.testing).to eq("Testing")
|
321
|
+
end
|
322
|
+
|
323
|
+
it "allows the setter" do
|
324
|
+
person.testing = "Test"
|
325
|
+
expect(person.testing).to eq("Test")
|
326
|
+
end
|
327
|
+
|
328
|
+
it "allows the getter before_type_cast" do
|
329
|
+
expect(person.testing_before_type_cast).to eq("Testing")
|
330
|
+
end
|
331
|
+
|
332
|
+
it "returns true for respond_to?" do
|
333
|
+
expect(person.respond_to?(:testing)).to be_true
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
context "when the provided value needs mongoization" do
|
338
|
+
|
339
|
+
let(:new_years) do
|
340
|
+
DateTime.new(2013, 1, 1, 0, 0, 0)
|
341
|
+
end
|
342
|
+
|
343
|
+
before do
|
344
|
+
person[:new_years] = new_years
|
345
|
+
end
|
346
|
+
|
347
|
+
it "mongoizes the dynamic field" do
|
348
|
+
expect(person.new_years).to be_a(Time)
|
349
|
+
end
|
350
|
+
|
351
|
+
it "keeps the same value" do
|
352
|
+
expect(person.new_years).to eq(new_years)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe "#process" do
|
358
|
+
|
359
|
+
context "when attributes dont have fields defined" do
|
360
|
+
|
361
|
+
let(:attributes) do
|
362
|
+
{
|
363
|
+
nofieldstring: "Testing",
|
364
|
+
nofieldint: 5,
|
365
|
+
employer: Employer.new
|
366
|
+
}
|
367
|
+
end
|
368
|
+
|
369
|
+
context "when allowing dynamic fields" do
|
370
|
+
|
371
|
+
let!(:person) do
|
372
|
+
Person.new(attributes)
|
373
|
+
end
|
374
|
+
|
375
|
+
context "when attribute is a string" do
|
376
|
+
|
377
|
+
it "adds the string to the attributes" do
|
378
|
+
expect(person.attributes["nofieldstring"]).to eq("Testing")
|
379
|
+
end
|
380
|
+
end
|
381
|
+
|
382
|
+
context "when attribute is not a string" do
|
383
|
+
|
384
|
+
it "adds a cast value to the attributes" do
|
385
|
+
expect(person.attributes["nofieldint"]).to eq(5)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
|
390
|
+
context "when not allowing dynamic fields" do
|
391
|
+
|
392
|
+
it "raises an unknown attribute error on instantiation" do
|
393
|
+
expect {
|
394
|
+
Account.new({ anothernew: "Test" })
|
395
|
+
}.to raise_error(Mongoid::Errors::UnknownAttribute)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
400
|
+
context "when supplied hash has string values" do
|
401
|
+
|
402
|
+
let(:bson_id) do
|
403
|
+
Moped::BSON::ObjectId.new
|
404
|
+
end
|
405
|
+
|
406
|
+
let!(:attributes) do
|
407
|
+
{
|
408
|
+
title: "value",
|
409
|
+
age: "30",
|
410
|
+
terms: "true",
|
411
|
+
score: "",
|
412
|
+
name: {
|
413
|
+
_id: "2", first_name: "Test", last_name: "User"
|
414
|
+
},
|
415
|
+
addresses: [
|
416
|
+
{ _id: "3", street: "First Street" },
|
417
|
+
{ _id: "4", street: "Second Street" }
|
418
|
+
]
|
419
|
+
}
|
420
|
+
end
|
421
|
+
|
422
|
+
let!(:person) do
|
423
|
+
Person.new(attributes)
|
424
|
+
end
|
425
|
+
|
426
|
+
it "casts integers" do
|
427
|
+
expect(person[:age]).to eq(30)
|
428
|
+
end
|
429
|
+
|
430
|
+
it "casts booleans" do
|
431
|
+
expect(person[:terms]).to be_true
|
432
|
+
end
|
433
|
+
|
434
|
+
it "sets empty strings to nil" do
|
435
|
+
expect(person[:score]).to be_nil
|
436
|
+
end
|
437
|
+
end
|
438
|
+
|
439
|
+
context "when associations provided in the attributes" do
|
440
|
+
|
441
|
+
context "when association is a has_one" do
|
442
|
+
|
443
|
+
let(:name) do
|
444
|
+
Name.new(first_name: "Testy")
|
445
|
+
end
|
446
|
+
|
447
|
+
let(:attributes) do
|
448
|
+
{ name: name }
|
449
|
+
end
|
450
|
+
|
451
|
+
let(:person) do
|
452
|
+
Person.new(attributes)
|
453
|
+
end
|
454
|
+
|
455
|
+
it "sets the associations" do
|
456
|
+
expect(person.name).to eq(name)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
|
460
|
+
context "when association is a references_one" do
|
461
|
+
|
462
|
+
let(:game) do
|
463
|
+
Game.new(score: 100)
|
464
|
+
end
|
465
|
+
|
466
|
+
let(:attributes) do
|
467
|
+
{ game: game }
|
468
|
+
end
|
469
|
+
|
470
|
+
let!(:person) do
|
471
|
+
Person.new(attributes)
|
472
|
+
end
|
473
|
+
|
474
|
+
it "sets the parent association" do
|
475
|
+
expect(person.game).to eq(game)
|
476
|
+
end
|
477
|
+
|
478
|
+
it "sets the inverse association" do
|
479
|
+
expect(game.person).to eq(person)
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
context "when association is a embedded_in" do
|
484
|
+
|
485
|
+
let(:person) do
|
486
|
+
Person.new
|
487
|
+
end
|
488
|
+
|
489
|
+
let(:name) do
|
490
|
+
Name.new(first_name: "Tyler", person: person)
|
491
|
+
end
|
492
|
+
|
493
|
+
it "sets the association" do
|
494
|
+
expect(name.person).to eq(person)
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
context "when non-associations provided in the attributes" do
|
500
|
+
|
501
|
+
let(:employer) do
|
502
|
+
Employer.new
|
503
|
+
end
|
504
|
+
|
505
|
+
let(:attributes) do
|
506
|
+
{ employer_id: employer.id, title: "Sir" }
|
507
|
+
end
|
508
|
+
|
509
|
+
let(:person) do
|
510
|
+
Person.new(attributes)
|
511
|
+
end
|
512
|
+
|
513
|
+
it "calls the setter for the association" do
|
514
|
+
expect(person.employer_id).to eq("1")
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
context "when an empty array is provided in the attributes" do
|
519
|
+
|
520
|
+
let(:attributes) do
|
521
|
+
{ aliases: [] }
|
522
|
+
end
|
523
|
+
|
524
|
+
let(:person) do
|
525
|
+
Person.new(attributes)
|
526
|
+
end
|
527
|
+
|
528
|
+
it "sets the empty array" do
|
529
|
+
expect(person.aliases).to be_empty
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
context "when an empty hash is provided in the attributes" do
|
534
|
+
|
535
|
+
let(:attributes) do
|
536
|
+
{ map: {} }
|
537
|
+
end
|
538
|
+
|
539
|
+
let(:person) do
|
540
|
+
Person.new(attributes)
|
541
|
+
end
|
542
|
+
|
543
|
+
it "sets the empty hash" do
|
544
|
+
expect(person.map).to eq({})
|
545
|
+
end
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
context "updating when attributes already exist" do
|
550
|
+
|
551
|
+
let(:person) do
|
552
|
+
Person.new(title: "Sir")
|
553
|
+
end
|
554
|
+
|
555
|
+
let(:attributes) do
|
556
|
+
{ dob: "2000-01-01" }
|
557
|
+
end
|
558
|
+
|
559
|
+
before do
|
560
|
+
person.process_attributes(attributes)
|
561
|
+
end
|
562
|
+
|
563
|
+
it "only overwrites supplied attributes" do
|
564
|
+
expect(person.title).to eq("Sir")
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
describe "#read_attribute" do
|
569
|
+
|
570
|
+
context "when the document is a new record" do
|
571
|
+
|
572
|
+
let(:person) do
|
573
|
+
Person.new
|
574
|
+
end
|
575
|
+
|
576
|
+
context "when attribute does not exist" do
|
577
|
+
|
578
|
+
it "returns the default value" do
|
579
|
+
expect(person.age).to eq(100)
|
580
|
+
expect(person.pets).to be_false
|
581
|
+
end
|
582
|
+
|
583
|
+
end
|
584
|
+
|
585
|
+
context "when attribute is not accessible" do
|
586
|
+
|
587
|
+
before do
|
588
|
+
person.owner_id = 5
|
589
|
+
end
|
590
|
+
|
591
|
+
it "returns the value" do
|
592
|
+
expect(person.read_attribute(:owner_id)).to eq(5)
|
593
|
+
end
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
context "when the document is an existing record" do
|
598
|
+
|
599
|
+
let(:person) do
|
600
|
+
Person.create
|
601
|
+
end
|
602
|
+
|
603
|
+
context "when the attribute does not exist" do
|
604
|
+
|
605
|
+
before do
|
606
|
+
person.collection
|
607
|
+
.find({ _id: person.id })
|
608
|
+
.update({ "$unset" => { age: 1 }})
|
609
|
+
Mongoid.raise_not_found_error = false
|
610
|
+
person.reload
|
611
|
+
Mongoid.raise_not_found_error = true
|
612
|
+
end
|
613
|
+
|
614
|
+
it "returns the default value" do
|
615
|
+
expect(person.age).to eq(100)
|
616
|
+
end
|
617
|
+
end
|
618
|
+
end
|
619
|
+
|
620
|
+
context "when attribute has an aliased name" do
|
621
|
+
|
622
|
+
let(:person) do
|
623
|
+
Person.new
|
624
|
+
end
|
625
|
+
|
626
|
+
before(:each) do
|
627
|
+
person.write_attribute(:t, "aliased field to test")
|
628
|
+
end
|
629
|
+
|
630
|
+
it "returns the value of the aliased field" do
|
631
|
+
expect(person.read_attribute(:test)).to eq("aliased field to test")
|
632
|
+
end
|
633
|
+
end
|
634
|
+
end
|
635
|
+
|
636
|
+
describe "#read_attribute_before_type_cast" do
|
637
|
+
let(:person) do
|
638
|
+
Person.create
|
639
|
+
end
|
640
|
+
|
641
|
+
context "when the attribute has not yet been assigned" do
|
642
|
+
|
643
|
+
it "returns the default value" do
|
644
|
+
expect(person.age_before_type_cast).to eq(100)
|
645
|
+
end
|
646
|
+
end
|
647
|
+
|
648
|
+
context "after the attribute has been assigned" do
|
649
|
+
|
650
|
+
it "returns the default value" do
|
651
|
+
person.age = "old"
|
652
|
+
expect(person.age_before_type_cast).to eq("old")
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
|
658
|
+
describe "#attribute_present?" do
|
659
|
+
|
660
|
+
context "when document is a new record" do
|
661
|
+
|
662
|
+
let(:person) do
|
663
|
+
Person.new
|
664
|
+
end
|
665
|
+
|
666
|
+
context "when attribute does not exist" do
|
667
|
+
|
668
|
+
it "returns false" do
|
669
|
+
expect(person.attribute_present?(:owner_id)).to be_false
|
670
|
+
end
|
671
|
+
end
|
672
|
+
|
673
|
+
context "when attribute does exist" do
|
674
|
+
before do
|
675
|
+
person.owner_id = 5
|
676
|
+
end
|
677
|
+
|
678
|
+
it "returns true" do
|
679
|
+
expect(person.attribute_present?(:owner_id)).to be_true
|
680
|
+
end
|
681
|
+
end
|
682
|
+
end
|
683
|
+
|
684
|
+
context "when the document is an existing record" do
|
685
|
+
|
686
|
+
let(:person) do
|
687
|
+
Person.create
|
688
|
+
end
|
689
|
+
|
690
|
+
context "when the attribute does not exist" do
|
691
|
+
|
692
|
+
before do
|
693
|
+
person.collection
|
694
|
+
.find({ _id: person.id })
|
695
|
+
.update({ "$unset" => { age: 1 }})
|
696
|
+
Mongoid.raise_not_found_error = false
|
697
|
+
person.reload
|
698
|
+
Mongoid.raise_not_found_error = true
|
699
|
+
end
|
700
|
+
|
701
|
+
it "returns true" do
|
702
|
+
expect(person.attribute_present?(:age)).to be_true
|
703
|
+
end
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
context "when the value is boolean" do
|
708
|
+
|
709
|
+
let(:person) do
|
710
|
+
Person.new
|
711
|
+
end
|
712
|
+
|
713
|
+
context "when attribute does not exist" do
|
714
|
+
|
715
|
+
context "when the value is true" do
|
716
|
+
|
717
|
+
it "return true" do
|
718
|
+
person.terms = false
|
719
|
+
expect(person.attribute_present?(:terms)).to be_true
|
720
|
+
end
|
721
|
+
end
|
722
|
+
|
723
|
+
context "when the value is false" do
|
724
|
+
|
725
|
+
it "return true" do
|
726
|
+
person.terms = false
|
727
|
+
expect(person.attribute_present?(:terms)).to be_true
|
728
|
+
end
|
729
|
+
end
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
context "when the value is blank string" do
|
734
|
+
|
735
|
+
let(:person) do
|
736
|
+
Person.new(title: '')
|
737
|
+
end
|
738
|
+
|
739
|
+
it "return false" do
|
740
|
+
expect(person.attribute_present?(:title)).to be_false
|
741
|
+
end
|
742
|
+
end
|
743
|
+
end
|
744
|
+
|
745
|
+
describe "#has_attribute?" do
|
746
|
+
|
747
|
+
let(:person) do
|
748
|
+
Person.new(title: "sir")
|
749
|
+
end
|
750
|
+
|
751
|
+
context "when the key is in the attributes" do
|
752
|
+
|
753
|
+
context "when provided a symbol" do
|
754
|
+
|
755
|
+
it "returns true" do
|
756
|
+
expect(person.has_attribute?(:title)).to be_true
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
context "when provided a string" do
|
761
|
+
|
762
|
+
it "returns true" do
|
763
|
+
expect(person.has_attribute?("title")).to be_true
|
764
|
+
end
|
765
|
+
end
|
766
|
+
end
|
767
|
+
|
768
|
+
context "when the key is not in the attributes" do
|
769
|
+
|
770
|
+
it "returns false" do
|
771
|
+
expect(person.has_attribute?(:employer_id)).to be_false
|
772
|
+
end
|
773
|
+
end
|
774
|
+
end
|
775
|
+
|
776
|
+
describe '#has_attribute_before_type_cast?' do
|
777
|
+
|
778
|
+
let(:person) do
|
779
|
+
Person.new
|
780
|
+
end
|
781
|
+
|
782
|
+
context "before the attribute has been assigned" do
|
783
|
+
|
784
|
+
it "returns false" do
|
785
|
+
expect(person.has_attribute_before_type_cast?(:age)).to be_false
|
786
|
+
end
|
787
|
+
end
|
788
|
+
|
789
|
+
context "after the attribute has been assigned" do
|
790
|
+
|
791
|
+
it "returns true" do
|
792
|
+
person.age = 'old'
|
793
|
+
expect(person.has_attribute_before_type_cast?(:age)).to be_true
|
794
|
+
end
|
795
|
+
end
|
796
|
+
end
|
797
|
+
|
798
|
+
describe "#remove_attribute" do
|
799
|
+
|
800
|
+
context "when the attribute exists" do
|
801
|
+
|
802
|
+
let(:person) do
|
803
|
+
Person.create(title: "Sir")
|
804
|
+
end
|
805
|
+
|
806
|
+
before do
|
807
|
+
person.remove_attribute(:title)
|
808
|
+
end
|
809
|
+
|
810
|
+
it "removes the attribute" do
|
811
|
+
expect(person.title).to be_nil
|
812
|
+
end
|
813
|
+
|
814
|
+
it "removes the key from the attributes hash" do
|
815
|
+
expect(person.has_attribute?(:title)).to be_false
|
816
|
+
end
|
817
|
+
|
818
|
+
context "when saving after the removal" do
|
819
|
+
|
820
|
+
before do
|
821
|
+
person.save
|
822
|
+
end
|
823
|
+
|
824
|
+
it "persists the removal" do
|
825
|
+
expect(person.reload.has_attribute?(:title)).to be_false
|
826
|
+
end
|
827
|
+
end
|
828
|
+
end
|
829
|
+
|
830
|
+
context "when the attribute exists in embedded document" do
|
831
|
+
|
832
|
+
let(:pet) do
|
833
|
+
Animal.new(name: "Cat")
|
834
|
+
end
|
835
|
+
|
836
|
+
let(:person) do
|
837
|
+
Person.new(pet: pet)
|
838
|
+
end
|
839
|
+
|
840
|
+
before do
|
841
|
+
person.save
|
842
|
+
person.pet.remove_attribute(:name)
|
843
|
+
end
|
844
|
+
|
845
|
+
it "removes the attribute" do
|
846
|
+
expect(person.pet.name).to be_nil
|
847
|
+
end
|
848
|
+
|
849
|
+
it "removes the key from the attributes hash" do
|
850
|
+
expect(person.pet.has_attribute?(:name)).to be_false
|
851
|
+
end
|
852
|
+
|
853
|
+
context "when saving after the removal" do
|
854
|
+
|
855
|
+
before do
|
856
|
+
person.save
|
857
|
+
end
|
858
|
+
|
859
|
+
it "persists the removal" do
|
860
|
+
expect(person.reload.pet.has_attribute?(:name)).to be_false
|
861
|
+
end
|
862
|
+
end
|
863
|
+
|
864
|
+
end
|
865
|
+
|
866
|
+
context "when the attribute does not exist" do
|
867
|
+
|
868
|
+
let(:person) do
|
869
|
+
Person.new
|
870
|
+
end
|
871
|
+
|
872
|
+
before do
|
873
|
+
person.remove_attribute(:title)
|
874
|
+
end
|
875
|
+
|
876
|
+
it "does not fail" do
|
877
|
+
expect(person.title).to be_nil
|
878
|
+
end
|
879
|
+
end
|
880
|
+
|
881
|
+
context "when the document is new" do
|
882
|
+
|
883
|
+
let(:person) do
|
884
|
+
Person.new(title: "sir")
|
885
|
+
end
|
886
|
+
|
887
|
+
before do
|
888
|
+
person.remove_attribute(:title)
|
889
|
+
end
|
890
|
+
|
891
|
+
it "does not add a delayed unset operation" do
|
892
|
+
expect(person.delayed_atomic_unsets).to be_empty
|
893
|
+
end
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
897
|
+
describe "#respond_to?" do
|
898
|
+
|
899
|
+
context "when allowing dynamic fields" do
|
900
|
+
|
901
|
+
let(:person) do
|
902
|
+
Person.new
|
903
|
+
end
|
904
|
+
|
905
|
+
context "when asking for the getter" do
|
906
|
+
|
907
|
+
context "when the attribute exists" do
|
908
|
+
|
909
|
+
before do
|
910
|
+
person[:attr] = "test"
|
911
|
+
end
|
912
|
+
|
913
|
+
it "returns true" do
|
914
|
+
expect(person).to respond_to(:attr)
|
915
|
+
end
|
916
|
+
end
|
917
|
+
|
918
|
+
context "when the attribute does not exist" do
|
919
|
+
|
920
|
+
it "returns false" do
|
921
|
+
expect(person).to_not respond_to(:attr)
|
922
|
+
end
|
923
|
+
end
|
924
|
+
end
|
925
|
+
|
926
|
+
context "when asking for the setter" do
|
927
|
+
|
928
|
+
context "when the attribute exists" do
|
929
|
+
|
930
|
+
before do
|
931
|
+
person[:attr] = "test"
|
932
|
+
end
|
933
|
+
|
934
|
+
it "returns true" do
|
935
|
+
expect(person).to respond_to(:attr=)
|
936
|
+
end
|
937
|
+
end
|
938
|
+
|
939
|
+
context "when the attribute does not exist" do
|
940
|
+
|
941
|
+
it "returns false" do
|
942
|
+
expect(person).to_not respond_to(:attr=)
|
943
|
+
end
|
944
|
+
end
|
945
|
+
end
|
946
|
+
end
|
947
|
+
|
948
|
+
context "when not allowing dynamic fields" do
|
949
|
+
|
950
|
+
let(:bar) do
|
951
|
+
Bar.new
|
952
|
+
end
|
953
|
+
|
954
|
+
context "when asking for the getter" do
|
955
|
+
|
956
|
+
it "returns false" do
|
957
|
+
expect(bar).to_not respond_to(:attr)
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
context "when asking for the setter" do
|
962
|
+
|
963
|
+
it "returns false" do
|
964
|
+
expect(bar).to_not respond_to(:attr=)
|
965
|
+
end
|
966
|
+
end
|
967
|
+
end
|
968
|
+
end
|
969
|
+
|
970
|
+
describe "#write_attribute" do
|
971
|
+
|
972
|
+
context "when attribute does not exist" do
|
973
|
+
|
974
|
+
let(:person) do
|
975
|
+
Person.new
|
976
|
+
end
|
977
|
+
|
978
|
+
it "returns the default value" do
|
979
|
+
expect(person.age).to eq(100)
|
980
|
+
end
|
981
|
+
end
|
982
|
+
|
983
|
+
context "when setting an attribute that needs type casting" do
|
984
|
+
let(:person) do
|
985
|
+
Person.new(age: "old")
|
986
|
+
end
|
987
|
+
|
988
|
+
it "should store the attribute before type cast" do
|
989
|
+
expect(person.age_before_type_cast).to eq("old")
|
990
|
+
end
|
991
|
+
end
|
992
|
+
|
993
|
+
context "when setting the attribute to nil" do
|
994
|
+
|
995
|
+
let(:person) do
|
996
|
+
Person.new(age: nil)
|
997
|
+
end
|
998
|
+
|
999
|
+
it "does not use the default value" do
|
1000
|
+
expect(person.age).to be_nil
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
context "when field has a default value" do
|
1005
|
+
|
1006
|
+
let(:person) do
|
1007
|
+
Person.new
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
before do
|
1011
|
+
person.terms = true
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
it "allows overwriting of the default value" do
|
1015
|
+
expect(person.terms).to be_true
|
1016
|
+
end
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
context "when attribute has an aliased name" do
|
1020
|
+
|
1021
|
+
let(:person) do
|
1022
|
+
Person.new
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
before(:each) do
|
1026
|
+
person.write_attribute(:test, "aliased field to test")
|
1027
|
+
end
|
1028
|
+
|
1029
|
+
it "allows the field name to be udpated" do
|
1030
|
+
expect(person.t).to eq("aliased field to test")
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
describe "#typed_value_for" do
|
1036
|
+
|
1037
|
+
let(:person) do
|
1038
|
+
Person.new
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
context "when the key has been specified as a field" do
|
1042
|
+
|
1043
|
+
it "retuns the typed value" do
|
1044
|
+
person.send(:typed_value_for, "age", "51")
|
1045
|
+
end
|
1046
|
+
end
|
1047
|
+
|
1048
|
+
context "when the key has not been specified as a field" do
|
1049
|
+
|
1050
|
+
before do
|
1051
|
+
person.stub(:fields).and_return({})
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
it "returns the value" do
|
1055
|
+
person.send(:typed_value_for, "age", expect("51")).to eq("51")
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
describe "#apply_default_attributes" do
|
1061
|
+
|
1062
|
+
let(:person) do
|
1063
|
+
Person.new
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
it "typecasts proc values" do
|
1067
|
+
expect(person.age).to eq(100)
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
|
1071
|
+
[:attributes=, :write_attributes].each do |method|
|
1072
|
+
|
1073
|
+
describe "##{method}" do
|
1074
|
+
|
1075
|
+
context "when nested" do
|
1076
|
+
|
1077
|
+
let(:person) do
|
1078
|
+
Person.new
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
before do
|
1082
|
+
person.send(method, { videos: [{title: "Fight Club"}] })
|
1083
|
+
end
|
1084
|
+
|
1085
|
+
it "sets nested documents" do
|
1086
|
+
expect(person.videos.first.title).to eq("Fight Club")
|
1087
|
+
end
|
1088
|
+
end
|
1089
|
+
|
1090
|
+
context "typecasting" do
|
1091
|
+
|
1092
|
+
let(:person) do
|
1093
|
+
Person.new
|
1094
|
+
end
|
1095
|
+
|
1096
|
+
let(:attributes) do
|
1097
|
+
{ age: "50" }
|
1098
|
+
end
|
1099
|
+
|
1100
|
+
context "when passing a hash" do
|
1101
|
+
|
1102
|
+
before do
|
1103
|
+
person.send(method, attributes)
|
1104
|
+
end
|
1105
|
+
|
1106
|
+
it "properly casts values" do
|
1107
|
+
expect(person.age).to eq(50)
|
1108
|
+
end
|
1109
|
+
end
|
1110
|
+
|
1111
|
+
context "when passing nil" do
|
1112
|
+
|
1113
|
+
before do
|
1114
|
+
person.send(method, nil)
|
1115
|
+
end
|
1116
|
+
|
1117
|
+
it "does not set anything" do
|
1118
|
+
expect(person.age).to eq(100)
|
1119
|
+
end
|
1120
|
+
end
|
1121
|
+
end
|
1122
|
+
|
1123
|
+
context "on a parent document" do
|
1124
|
+
|
1125
|
+
context "when the parent has a has many through a has one" do
|
1126
|
+
|
1127
|
+
let(:owner) do
|
1128
|
+
PetOwner.new(title: "Mr")
|
1129
|
+
end
|
1130
|
+
|
1131
|
+
let(:pet) do
|
1132
|
+
Pet.new(name: "Fido")
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
let(:vet_visit) do
|
1136
|
+
VetVisit.new(date: Date.today)
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
before do
|
1140
|
+
owner.pet = pet
|
1141
|
+
pet.vet_visits = [ vet_visit ]
|
1142
|
+
owner.send(method, { pet: { name: "Bingo" } })
|
1143
|
+
end
|
1144
|
+
|
1145
|
+
it "does not overwrite child attributes if not in the hash" do
|
1146
|
+
expect(owner.pet.name).to eq("Bingo")
|
1147
|
+
expect(owner.pet.vet_visits.size).to eq(1)
|
1148
|
+
end
|
1149
|
+
end
|
1150
|
+
|
1151
|
+
context "when parent destroy all child on setter" do
|
1152
|
+
|
1153
|
+
let(:owner) do
|
1154
|
+
PetOwner.create!(title: "Mr")
|
1155
|
+
end
|
1156
|
+
|
1157
|
+
let(:pet) do
|
1158
|
+
Pet.create!(name: "Kika", pet_owner: owner)
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
let!(:vet_visit) do
|
1162
|
+
pet.vet_visits.create!(date: Date.today)
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
before do
|
1166
|
+
pet.send(method, { visits_count: 3 })
|
1167
|
+
pet.save!
|
1168
|
+
end
|
1169
|
+
|
1170
|
+
it "has 3 new entries" do
|
1171
|
+
expect(pet.vet_visits.count).to eq(3)
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
it "persists the changes" do
|
1175
|
+
expect(pet.reload.vet_visits.count).to eq(3)
|
1176
|
+
end
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
context "when the parent has an empty embeds_many" do
|
1180
|
+
|
1181
|
+
let(:person) do
|
1182
|
+
Person.new
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
let(:attributes) do
|
1186
|
+
{ services: [] }
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
it "does not raise an error" do
|
1190
|
+
person.send(method, attributes)
|
1191
|
+
end
|
1192
|
+
end
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
context "on a child document" do
|
1196
|
+
|
1197
|
+
context "when child is part of a has one" do
|
1198
|
+
|
1199
|
+
let(:person) do
|
1200
|
+
Person.new(title: "Sir", age: 30)
|
1201
|
+
end
|
1202
|
+
|
1203
|
+
let(:name) do
|
1204
|
+
Name.new(first_name: "Test", last_name: "User")
|
1205
|
+
end
|
1206
|
+
|
1207
|
+
before do
|
1208
|
+
person.name = name
|
1209
|
+
name.send(method, first_name: "Test2", last_name: "User2")
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
it "sets the child attributes on the parent" do
|
1213
|
+
expect(name.attributes).to eq(
|
1214
|
+
{ "_id" => "Test-User", "first_name" => "Test2", "last_name" => "User2" }
|
1215
|
+
)
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
context "when child is part of a has many" do
|
1220
|
+
|
1221
|
+
let(:person) do
|
1222
|
+
Person.new(title: "Sir")
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
let(:address) do
|
1226
|
+
Address.new(street: "Test")
|
1227
|
+
end
|
1228
|
+
|
1229
|
+
before do
|
1230
|
+
person.addresses << address
|
1231
|
+
address.send(method, "street" => "Test2")
|
1232
|
+
end
|
1233
|
+
|
1234
|
+
it "updates the child attributes on the parent" do
|
1235
|
+
expect(address.attributes).to eq(
|
1236
|
+
{ "_id" => "test", "street" => "Test2" }
|
1237
|
+
)
|
1238
|
+
end
|
1239
|
+
end
|
1240
|
+
end
|
1241
|
+
end
|
1242
|
+
end
|
1243
|
+
|
1244
|
+
describe "#alias_attribute" do
|
1245
|
+
|
1246
|
+
let(:product) do
|
1247
|
+
Product.new
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
context "when checking against the alias" do
|
1251
|
+
|
1252
|
+
before do
|
1253
|
+
product.cost = 500
|
1254
|
+
end
|
1255
|
+
|
1256
|
+
it "aliases the getter" do
|
1257
|
+
expect(product.cost).to eq(500)
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
it "aliases the existance check" do
|
1261
|
+
expect(product.cost?).to be_true
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
it "aliases *_changed?" do
|
1265
|
+
expect(product.cost_changed?).to be_true
|
1266
|
+
end
|
1267
|
+
|
1268
|
+
it "aliases *_change" do
|
1269
|
+
expect(product.cost_change).to eq([ nil, 500 ])
|
1270
|
+
end
|
1271
|
+
|
1272
|
+
it "aliases *_will_change!" do
|
1273
|
+
expect(product).to respond_to(:cost_will_change!)
|
1274
|
+
end
|
1275
|
+
|
1276
|
+
it "aliases *_was" do
|
1277
|
+
expect(product.cost_was).to be_nil
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
it "aliases reset_*!" do
|
1281
|
+
product.reset_cost!
|
1282
|
+
expect(product.cost).to be_nil
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
it "aliases *_before_type_cast" do
|
1286
|
+
product.cost = "expensive"
|
1287
|
+
expect(product.cost_before_type_cast).to eq("expensive")
|
1288
|
+
end
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
context "when checking against the original" do
|
1292
|
+
|
1293
|
+
before do
|
1294
|
+
product.price = 500
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
it "aliases the getter" do
|
1298
|
+
expect(product.price).to eq(500)
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
it "aliases the existance check" do
|
1302
|
+
expect(product.price?).to be_true
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
it "aliases *_changed?" do
|
1306
|
+
expect(product.price_changed?).to be_true
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
it "aliases *_change" do
|
1310
|
+
expect(product.price_change).to eq([ nil, 500 ])
|
1311
|
+
end
|
1312
|
+
|
1313
|
+
it "aliases *_will_change!" do
|
1314
|
+
expect(product).to respond_to(:price_will_change!)
|
1315
|
+
end
|
1316
|
+
|
1317
|
+
it "aliases *_was" do
|
1318
|
+
expect(product.price_was).to be_nil
|
1319
|
+
end
|
1320
|
+
|
1321
|
+
it "aliases reset_*!" do
|
1322
|
+
product.reset_price!
|
1323
|
+
expect(product.price).to be_nil
|
1324
|
+
end
|
1325
|
+
end
|
1326
|
+
end
|
1327
|
+
|
1328
|
+
context "when persisting nil attributes" do
|
1329
|
+
|
1330
|
+
let!(:person) do
|
1331
|
+
Person.create(score: nil)
|
1332
|
+
end
|
1333
|
+
|
1334
|
+
it "has an entry in the attributes" do
|
1335
|
+
expect(person.reload.attributes).to have_key("score")
|
1336
|
+
end
|
1337
|
+
end
|
1338
|
+
|
1339
|
+
context "with a default last_drink_taken_at" do
|
1340
|
+
|
1341
|
+
let(:person) do
|
1342
|
+
Person.new
|
1343
|
+
end
|
1344
|
+
|
1345
|
+
it "saves the default" do
|
1346
|
+
expect { person.save }.to_not raise_error
|
1347
|
+
expect(person.last_drink_taken_at).to eq(1.day.ago.in_time_zone("Alaska").to_date)
|
1348
|
+
end
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
context "when default values are defined" do
|
1352
|
+
|
1353
|
+
context "when no value exists in the database" do
|
1354
|
+
|
1355
|
+
let(:person) do
|
1356
|
+
Person.create
|
1357
|
+
end
|
1358
|
+
|
1359
|
+
it "applies the default value" do
|
1360
|
+
expect(person.last_drink_taken_at).to eq(1.day.ago.in_time_zone("Alaska").to_date)
|
1361
|
+
end
|
1362
|
+
end
|
1363
|
+
|
1364
|
+
context "when a value exists in the database" do
|
1365
|
+
|
1366
|
+
context "when the value is not nil" do
|
1367
|
+
|
1368
|
+
let!(:person) do
|
1369
|
+
Person.create(age: 50)
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
let(:from_db) do
|
1373
|
+
Person.find(person.id)
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
it "does not set the default" do
|
1377
|
+
expect(from_db.age).to eq(50)
|
1378
|
+
end
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
context "when the value is explicitly nil" do
|
1382
|
+
|
1383
|
+
let!(:person) do
|
1384
|
+
Person.create(age: nil)
|
1385
|
+
end
|
1386
|
+
|
1387
|
+
let(:from_db) do
|
1388
|
+
Person.find(person.id)
|
1389
|
+
end
|
1390
|
+
|
1391
|
+
it "does not set the default" do
|
1392
|
+
expect(from_db.age).to be_nil
|
1393
|
+
end
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
context "when the default is a proc" do
|
1397
|
+
|
1398
|
+
let!(:account) do
|
1399
|
+
Account.create(name: "savings", balance: "100")
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
let(:from_db) do
|
1403
|
+
Account.find(account.id)
|
1404
|
+
end
|
1405
|
+
|
1406
|
+
it "applies the defaults after all attributes are set" do
|
1407
|
+
expect(from_db).to be_balanced
|
1408
|
+
end
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
end
|
1412
|
+
end
|