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,2305 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Validatable::UniquenessValidator do
|
4
|
+
|
5
|
+
describe "#valid?" do
|
6
|
+
|
7
|
+
context "when the document is a root document" do
|
8
|
+
|
9
|
+
context "when adding custom persistence options" do
|
10
|
+
|
11
|
+
before do
|
12
|
+
Dictionary.validates_uniqueness_of :name
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
Dictionary.reset_callbacks(:validate)
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when persisting to another collection" do
|
20
|
+
|
21
|
+
before do
|
22
|
+
Dictionary.with(collection: "dicts").create(name: "websters")
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when the document is not valid" do
|
26
|
+
|
27
|
+
let(:websters) do
|
28
|
+
Dictionary.with(collection: "dicts").new(name: "websters")
|
29
|
+
end
|
30
|
+
|
31
|
+
it "performs the validation on the correct collection" do
|
32
|
+
expect(websters).to_not be_valid
|
33
|
+
end
|
34
|
+
|
35
|
+
it "adds the uniqueness error" do
|
36
|
+
websters.valid?
|
37
|
+
expect(websters.errors[:name]).to_not be_nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "clears the persistence options in the thread local" do
|
41
|
+
websters.valid?
|
42
|
+
expect(Dictionary.persistence_options).to be_nil
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "when the document is valid" do
|
47
|
+
|
48
|
+
let(:oxford) do
|
49
|
+
Dictionary.with(collection: "dicts").new(name: "oxford")
|
50
|
+
end
|
51
|
+
|
52
|
+
it "performs the validation on the correct collection" do
|
53
|
+
expect(oxford).to be_valid
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "when the document contains no compound key" do
|
60
|
+
|
61
|
+
context "when validating a relation" do
|
62
|
+
|
63
|
+
before do
|
64
|
+
Word.validates_uniqueness_of :dictionary
|
65
|
+
end
|
66
|
+
|
67
|
+
after do
|
68
|
+
Word.reset_callbacks(:validate)
|
69
|
+
end
|
70
|
+
|
71
|
+
context "when the attribute id is unique" do
|
72
|
+
|
73
|
+
let(:dictionary) do
|
74
|
+
Dictionary.create
|
75
|
+
end
|
76
|
+
|
77
|
+
let(:word) do
|
78
|
+
Word.new(dictionary: dictionary)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "returns true" do
|
82
|
+
expect(word).to be_valid
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when the field name is aliased" do
|
88
|
+
|
89
|
+
before do
|
90
|
+
Dictionary.create!(language: "en")
|
91
|
+
end
|
92
|
+
|
93
|
+
let(:dictionary) do
|
94
|
+
Dictionary.new(language: "en")
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
Dictionary.reset_callbacks(:validate)
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when the validation uses the aliased name" do
|
102
|
+
|
103
|
+
before do
|
104
|
+
Dictionary.validates_uniqueness_of :language
|
105
|
+
end
|
106
|
+
|
107
|
+
it "correctly detects a uniqueness conflict" do
|
108
|
+
expect(dictionary).to_not be_valid
|
109
|
+
end
|
110
|
+
|
111
|
+
it "adds the uniqueness error to the aliased field name" do
|
112
|
+
dictionary.valid?
|
113
|
+
expect(dictionary.errors).to have_key(:language)
|
114
|
+
expect(dictionary.errors[:language]).to eq([ "is already taken" ])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when the validation uses the underlying field name" do
|
119
|
+
|
120
|
+
before do
|
121
|
+
Dictionary.validates_uniqueness_of :l
|
122
|
+
end
|
123
|
+
|
124
|
+
it "correctly detects a uniqueness conflict" do
|
125
|
+
expect(dictionary).to_not be_valid
|
126
|
+
end
|
127
|
+
|
128
|
+
it "adds the uniqueness error to the underlying field name" do
|
129
|
+
dictionary.valid?
|
130
|
+
expect(dictionary.errors).to have_key(:l)
|
131
|
+
expect(dictionary.errors[:l]).to eq([ "is already taken" ])
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when the field is localized" do
|
137
|
+
|
138
|
+
context "when no scope is provided" do
|
139
|
+
|
140
|
+
context "when case sensitive is true" do
|
141
|
+
|
142
|
+
before do
|
143
|
+
Dictionary.validates_uniqueness_of :description
|
144
|
+
end
|
145
|
+
|
146
|
+
after do
|
147
|
+
Dictionary.reset_callbacks(:validate)
|
148
|
+
end
|
149
|
+
|
150
|
+
context "when the attribute is unique" do
|
151
|
+
|
152
|
+
context "when single localization" do
|
153
|
+
|
154
|
+
before do
|
155
|
+
Dictionary.with(safe: true).create(description: "english")
|
156
|
+
end
|
157
|
+
|
158
|
+
let(:dictionary) do
|
159
|
+
Dictionary.new(description: "English")
|
160
|
+
end
|
161
|
+
|
162
|
+
it "returns true" do
|
163
|
+
expect(dictionary).to be_valid
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
context "when multiple localizations" do
|
168
|
+
|
169
|
+
before do
|
170
|
+
Dictionary.with(safe: true).
|
171
|
+
create(description_translations: { "en" => "english", "de" => "german" })
|
172
|
+
end
|
173
|
+
|
174
|
+
let(:dictionary) do
|
175
|
+
Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
|
176
|
+
end
|
177
|
+
|
178
|
+
it "returns true" do
|
179
|
+
expect(dictionary).to be_valid
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
context "when the attribute is not unique" do
|
185
|
+
|
186
|
+
context "when the document is not the match" do
|
187
|
+
|
188
|
+
context "when single localization" do
|
189
|
+
|
190
|
+
before do
|
191
|
+
Dictionary.with(safe: true).create(description: "english")
|
192
|
+
end
|
193
|
+
|
194
|
+
let(:dictionary) do
|
195
|
+
Dictionary.new(description: "english")
|
196
|
+
end
|
197
|
+
|
198
|
+
it "returns false" do
|
199
|
+
expect(dictionary).to_not be_valid
|
200
|
+
end
|
201
|
+
|
202
|
+
it "adds the uniqueness error" do
|
203
|
+
dictionary.valid?
|
204
|
+
expect(dictionary.errors[:description]).to eq([ "is already taken" ])
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
context "when multiple localizations" do
|
209
|
+
|
210
|
+
before do
|
211
|
+
Dictionary.with(safe: true).
|
212
|
+
create(description_translations: { "en" => "english", "de" => "german" })
|
213
|
+
end
|
214
|
+
|
215
|
+
let(:dictionary) do
|
216
|
+
Dictionary.new(description_translations: { "en" => "english", "de" => "German" })
|
217
|
+
end
|
218
|
+
|
219
|
+
it "returns false" do
|
220
|
+
expect(dictionary).to_not be_valid
|
221
|
+
end
|
222
|
+
|
223
|
+
it "adds the uniqueness error" do
|
224
|
+
dictionary.valid?
|
225
|
+
expect(dictionary.errors[:description]).to eq([ "is already taken" ])
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
context "when case sensitive is false" do
|
233
|
+
|
234
|
+
before do
|
235
|
+
Dictionary.validates_uniqueness_of :description, case_sensitive: false
|
236
|
+
end
|
237
|
+
|
238
|
+
after do
|
239
|
+
Dictionary.reset_callbacks(:validate)
|
240
|
+
end
|
241
|
+
|
242
|
+
context "when the attribute is unique" do
|
243
|
+
|
244
|
+
context "when there are no special characters" do
|
245
|
+
|
246
|
+
before do
|
247
|
+
Dictionary.with(safe: true).create(description: "english")
|
248
|
+
end
|
249
|
+
|
250
|
+
let(:dictionary) do
|
251
|
+
Dictionary.new(description: "german")
|
252
|
+
end
|
253
|
+
|
254
|
+
it "returns true" do
|
255
|
+
expect(dictionary).to be_valid
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
259
|
+
context "when special characters exist" do
|
260
|
+
|
261
|
+
before do
|
262
|
+
Dictionary.with(safe: true).create(description: "english")
|
263
|
+
end
|
264
|
+
|
265
|
+
let(:dictionary) do
|
266
|
+
Dictionary.new(description: "en@gl.ish")
|
267
|
+
end
|
268
|
+
|
269
|
+
it "returns true" do
|
270
|
+
expect(dictionary).to be_valid
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
context "when the attribute is not unique" do
|
276
|
+
|
277
|
+
context "when the document is not the match" do
|
278
|
+
|
279
|
+
context "when signle localization" do
|
280
|
+
|
281
|
+
before do
|
282
|
+
Dictionary.with(safe: true).create(description: "english")
|
283
|
+
end
|
284
|
+
|
285
|
+
let(:dictionary) do
|
286
|
+
Dictionary.new(description: "English")
|
287
|
+
end
|
288
|
+
|
289
|
+
it "returns false" do
|
290
|
+
expect(dictionary).to_not be_valid
|
291
|
+
end
|
292
|
+
|
293
|
+
it "adds the uniqueness error" do
|
294
|
+
dictionary.valid?
|
295
|
+
expect(dictionary.errors[:description]).to eq([ "is already taken" ])
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
context "when multiple localizations" do
|
300
|
+
|
301
|
+
before do
|
302
|
+
Dictionary.with(safe: true).
|
303
|
+
create(description_translations: { "en" => "english", "de" => "german" })
|
304
|
+
end
|
305
|
+
|
306
|
+
let(:dictionary) do
|
307
|
+
Dictionary.new(description_translations: { "en" => "English", "de" => "German" })
|
308
|
+
end
|
309
|
+
|
310
|
+
it "returns false" do
|
311
|
+
expect(dictionary).to_not be_valid
|
312
|
+
end
|
313
|
+
|
314
|
+
it "adds the uniqueness error" do
|
315
|
+
dictionary.valid?
|
316
|
+
expect(dictionary.errors[:description]).to eq([ "is already taken" ])
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "when the document is the match in the database" do
|
322
|
+
|
323
|
+
let!(:dictionary) do
|
324
|
+
Dictionary.with(safe: true).create(description: "english")
|
325
|
+
end
|
326
|
+
|
327
|
+
it "returns true" do
|
328
|
+
expect(dictionary).to be_valid
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context "when a scope is provided" do
|
336
|
+
|
337
|
+
before do
|
338
|
+
Dictionary.validates_uniqueness_of :description, scope: :name
|
339
|
+
end
|
340
|
+
|
341
|
+
after do
|
342
|
+
Dictionary.reset_callbacks(:validate)
|
343
|
+
end
|
344
|
+
|
345
|
+
context "when the attribute is not unique in the scope" do
|
346
|
+
|
347
|
+
context "when the document is not the match" do
|
348
|
+
|
349
|
+
before do
|
350
|
+
Dictionary.with(safe: true).
|
351
|
+
create(description: "english", name: "test")
|
352
|
+
end
|
353
|
+
|
354
|
+
let(:dictionary) do
|
355
|
+
Dictionary.new(description: "english", name: "test")
|
356
|
+
end
|
357
|
+
|
358
|
+
it "returns false" do
|
359
|
+
expect(dictionary).to_not be_valid
|
360
|
+
end
|
361
|
+
|
362
|
+
it "adds the uniqueness error" do
|
363
|
+
dictionary.valid?
|
364
|
+
expect(dictionary.errors[:description]).to eq([ "is already taken" ])
|
365
|
+
end
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context "when no scope is provided" do
|
372
|
+
|
373
|
+
before do
|
374
|
+
Dictionary.validates_uniqueness_of :name
|
375
|
+
end
|
376
|
+
|
377
|
+
after do
|
378
|
+
Dictionary.reset_callbacks(:validate)
|
379
|
+
end
|
380
|
+
|
381
|
+
context "when the attribute is unique" do
|
382
|
+
|
383
|
+
let!(:oxford) do
|
384
|
+
Dictionary.create(name: "Oxford")
|
385
|
+
end
|
386
|
+
|
387
|
+
let(:dictionary) do
|
388
|
+
Dictionary.new(name: "Webster")
|
389
|
+
end
|
390
|
+
|
391
|
+
it "returns true" do
|
392
|
+
expect(dictionary).to be_valid
|
393
|
+
end
|
394
|
+
|
395
|
+
context "when subsequently cloning the document" do
|
396
|
+
|
397
|
+
let(:clone) do
|
398
|
+
oxford.clone
|
399
|
+
end
|
400
|
+
|
401
|
+
it "returns false for the clone" do
|
402
|
+
expect(clone).to_not be_valid
|
403
|
+
end
|
404
|
+
end
|
405
|
+
end
|
406
|
+
|
407
|
+
context "when the attribute is not unique" do
|
408
|
+
|
409
|
+
context "when the document is not the match" do
|
410
|
+
|
411
|
+
before do
|
412
|
+
Dictionary.create(name: "Oxford")
|
413
|
+
end
|
414
|
+
|
415
|
+
let!(:dictionary) do
|
416
|
+
Dictionary.new(name: "Oxford")
|
417
|
+
end
|
418
|
+
|
419
|
+
it "returns false" do
|
420
|
+
expect(dictionary).to_not be_valid
|
421
|
+
end
|
422
|
+
|
423
|
+
it "adds the uniqueness error" do
|
424
|
+
dictionary.valid?
|
425
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
context "when the document is the match in the database" do
|
430
|
+
|
431
|
+
context "when the field has changed" do
|
432
|
+
|
433
|
+
let!(:dictionary) do
|
434
|
+
Dictionary.create(name: "Oxford")
|
435
|
+
end
|
436
|
+
|
437
|
+
it "returns true" do
|
438
|
+
expect(dictionary).to be_valid
|
439
|
+
end
|
440
|
+
end
|
441
|
+
|
442
|
+
context "when the field has not changed" do
|
443
|
+
|
444
|
+
before do
|
445
|
+
Dictionary.default_scoping = nil
|
446
|
+
end
|
447
|
+
|
448
|
+
let!(:dictionary) do
|
449
|
+
Dictionary.create!(name: "Oxford")
|
450
|
+
end
|
451
|
+
|
452
|
+
let!(:from_db) do
|
453
|
+
Dictionary.find(dictionary.id)
|
454
|
+
end
|
455
|
+
|
456
|
+
it "returns true" do
|
457
|
+
expect(from_db).to be_valid
|
458
|
+
end
|
459
|
+
|
460
|
+
it "does not touch the database" do
|
461
|
+
Dictionary.should_receive(:where).never
|
462
|
+
from_db.valid?
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
context "when a default scope is on the model" do
|
470
|
+
|
471
|
+
before do
|
472
|
+
Dictionary.validates_uniqueness_of :name
|
473
|
+
Dictionary.default_scope(Dictionary.where(year: 1990))
|
474
|
+
end
|
475
|
+
|
476
|
+
after do
|
477
|
+
Dictionary.send(:strip_default_scope, Dictionary.where(year: 1990))
|
478
|
+
Dictionary.reset_callbacks(:validate)
|
479
|
+
end
|
480
|
+
|
481
|
+
context "when the document with the unqiue attribute is not in default scope" do
|
482
|
+
|
483
|
+
context "when the attribute is not unique" do
|
484
|
+
|
485
|
+
before do
|
486
|
+
Dictionary.with(safe: true).create(name: "Oxford")
|
487
|
+
end
|
488
|
+
|
489
|
+
let(:dictionary) do
|
490
|
+
Dictionary.new(name: "Oxford")
|
491
|
+
end
|
492
|
+
|
493
|
+
it "returns false" do
|
494
|
+
expect(dictionary).to_not be_valid
|
495
|
+
end
|
496
|
+
end
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
context "when an aliased scope is provided" do
|
501
|
+
|
502
|
+
before do
|
503
|
+
Dictionary.validates_uniqueness_of :name, scope: :language
|
504
|
+
end
|
505
|
+
|
506
|
+
after do
|
507
|
+
Dictionary.reset_callbacks(:validate)
|
508
|
+
end
|
509
|
+
|
510
|
+
context "when the attribute is unique" do
|
511
|
+
|
512
|
+
before do
|
513
|
+
Dictionary.create(name: "Oxford", language: "English")
|
514
|
+
end
|
515
|
+
|
516
|
+
let(:dictionary) do
|
517
|
+
Dictionary.new(name: "Webster")
|
518
|
+
end
|
519
|
+
|
520
|
+
it "returns true" do
|
521
|
+
expect(dictionary).to be_valid
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
context "when the attribute is unique in the scope" do
|
526
|
+
|
527
|
+
before do
|
528
|
+
Dictionary.create(name: "Oxford", language: "English")
|
529
|
+
end
|
530
|
+
|
531
|
+
let(:dictionary) do
|
532
|
+
Dictionary.new(name: "Webster", language: "English")
|
533
|
+
end
|
534
|
+
|
535
|
+
it "returns true" do
|
536
|
+
expect(dictionary).to be_valid
|
537
|
+
end
|
538
|
+
end
|
539
|
+
|
540
|
+
context "when the attribute is not unique with no scope" do
|
541
|
+
|
542
|
+
before do
|
543
|
+
Dictionary.create(name: "Oxford", language: "English")
|
544
|
+
end
|
545
|
+
|
546
|
+
let(:dictionary) do
|
547
|
+
Dictionary.new(name: "Oxford")
|
548
|
+
end
|
549
|
+
|
550
|
+
it "returns true" do
|
551
|
+
expect(dictionary).to be_valid
|
552
|
+
end
|
553
|
+
end
|
554
|
+
|
555
|
+
context "when the attribute is not unique in another scope" do
|
556
|
+
|
557
|
+
before do
|
558
|
+
Dictionary.create(name: "Oxford", language: "English")
|
559
|
+
end
|
560
|
+
|
561
|
+
let(:dictionary) do
|
562
|
+
Dictionary.new(name: "Oxford", language: "Deutsch")
|
563
|
+
end
|
564
|
+
|
565
|
+
it "returns true" do
|
566
|
+
expect(dictionary).to be_valid
|
567
|
+
end
|
568
|
+
end
|
569
|
+
|
570
|
+
context "when the attribute is not unique in the same scope" do
|
571
|
+
|
572
|
+
context "when the document is not the match" do
|
573
|
+
|
574
|
+
before do
|
575
|
+
Dictionary.create(name: "Oxford", language: "English")
|
576
|
+
end
|
577
|
+
|
578
|
+
let(:dictionary) do
|
579
|
+
Dictionary.new(name: "Oxford", language: "English")
|
580
|
+
end
|
581
|
+
|
582
|
+
it "returns false" do
|
583
|
+
expect(dictionary).to_not be_valid
|
584
|
+
end
|
585
|
+
|
586
|
+
it "adds the uniqueness errors" do
|
587
|
+
dictionary.valid?
|
588
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
589
|
+
end
|
590
|
+
end
|
591
|
+
|
592
|
+
context "when the document is the match in the database" do
|
593
|
+
|
594
|
+
let!(:dictionary) do
|
595
|
+
Dictionary.create(name: "Oxford", language: "English")
|
596
|
+
end
|
597
|
+
|
598
|
+
it "returns true" do
|
599
|
+
expect(dictionary).to be_valid
|
600
|
+
end
|
601
|
+
end
|
602
|
+
end
|
603
|
+
end
|
604
|
+
|
605
|
+
context "when a single scope is provided" do
|
606
|
+
|
607
|
+
before do
|
608
|
+
Dictionary.validates_uniqueness_of :name, scope: :publisher
|
609
|
+
end
|
610
|
+
|
611
|
+
after do
|
612
|
+
Dictionary.reset_callbacks(:validate)
|
613
|
+
end
|
614
|
+
|
615
|
+
context "when the attribute is unique" do
|
616
|
+
|
617
|
+
before do
|
618
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
619
|
+
end
|
620
|
+
|
621
|
+
let(:dictionary) do
|
622
|
+
Dictionary.new(name: "Webster")
|
623
|
+
end
|
624
|
+
|
625
|
+
it "returns true" do
|
626
|
+
expect(dictionary).to be_valid
|
627
|
+
end
|
628
|
+
end
|
629
|
+
|
630
|
+
context "when the attribute is unique in the scope" do
|
631
|
+
|
632
|
+
before do
|
633
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
634
|
+
end
|
635
|
+
|
636
|
+
let(:dictionary) do
|
637
|
+
Dictionary.new(name: "Webster", publisher: "Amazon")
|
638
|
+
end
|
639
|
+
|
640
|
+
it "returns true" do
|
641
|
+
expect(dictionary).to be_valid
|
642
|
+
end
|
643
|
+
end
|
644
|
+
|
645
|
+
context "when uniqueness is violated due to scope change" do
|
646
|
+
|
647
|
+
let(:personal_folder) do
|
648
|
+
Folder.create!(name: "Personal")
|
649
|
+
end
|
650
|
+
|
651
|
+
let(:public_folder) do
|
652
|
+
Folder.create!(name: "Public")
|
653
|
+
end
|
654
|
+
|
655
|
+
before do
|
656
|
+
personal_folder.folder_items << FolderItem.new(name: "non-unique")
|
657
|
+
public_folder.folder_items << FolderItem.new(name: "non-unique")
|
658
|
+
end
|
659
|
+
|
660
|
+
let(:item) do
|
661
|
+
public_folder.folder_items.last
|
662
|
+
end
|
663
|
+
|
664
|
+
it "should set an error for associated object not being unique" do
|
665
|
+
item.update_attributes(folder_id: personal_folder.id)
|
666
|
+
expect(item.errors.messages[:name].first).to eq("is already taken")
|
667
|
+
end
|
668
|
+
end
|
669
|
+
|
670
|
+
context "when the attribute is not unique with no scope" do
|
671
|
+
|
672
|
+
before do
|
673
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
674
|
+
end
|
675
|
+
|
676
|
+
let(:dictionary) do
|
677
|
+
Dictionary.new(name: "Oxford")
|
678
|
+
end
|
679
|
+
|
680
|
+
it "returns true" do
|
681
|
+
expect(dictionary).to be_valid
|
682
|
+
end
|
683
|
+
end
|
684
|
+
|
685
|
+
context "when the attribute is not unique in another scope" do
|
686
|
+
|
687
|
+
before do
|
688
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
689
|
+
end
|
690
|
+
|
691
|
+
let(:dictionary) do
|
692
|
+
Dictionary.new(name: "Oxford", publisher: "Addison")
|
693
|
+
end
|
694
|
+
|
695
|
+
it "returns true" do
|
696
|
+
expect(dictionary).to be_valid
|
697
|
+
end
|
698
|
+
end
|
699
|
+
|
700
|
+
context "when the attribute is not unique in the same scope" do
|
701
|
+
|
702
|
+
context "when the document is not the match" do
|
703
|
+
|
704
|
+
before do
|
705
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
706
|
+
end
|
707
|
+
|
708
|
+
let(:dictionary) do
|
709
|
+
Dictionary.new(name: "Oxford", publisher: "Amazon")
|
710
|
+
end
|
711
|
+
|
712
|
+
it "returns false" do
|
713
|
+
expect(dictionary).to_not be_valid
|
714
|
+
end
|
715
|
+
|
716
|
+
it "adds the uniqueness errors" do
|
717
|
+
dictionary.valid?
|
718
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
719
|
+
end
|
720
|
+
end
|
721
|
+
|
722
|
+
context "when the document is the match in the database" do
|
723
|
+
|
724
|
+
let!(:dictionary) do
|
725
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
726
|
+
end
|
727
|
+
|
728
|
+
it "returns true" do
|
729
|
+
expect(dictionary).to be_valid
|
730
|
+
end
|
731
|
+
end
|
732
|
+
|
733
|
+
context "when one of the scopes is a time" do
|
734
|
+
|
735
|
+
before do
|
736
|
+
Dictionary.create(
|
737
|
+
name: "Oxford",
|
738
|
+
publisher: "Amazon",
|
739
|
+
published: 10.days.ago.to_time
|
740
|
+
)
|
741
|
+
end
|
742
|
+
|
743
|
+
let(:dictionary) do
|
744
|
+
Dictionary.new(
|
745
|
+
name: "Oxford",
|
746
|
+
publisher: "Amazon",
|
747
|
+
published: 10.days.ago.to_time
|
748
|
+
)
|
749
|
+
end
|
750
|
+
|
751
|
+
it "returns false" do
|
752
|
+
expect(dictionary).to_not be_valid
|
753
|
+
end
|
754
|
+
|
755
|
+
it "adds the uniqueness errors" do
|
756
|
+
dictionary.valid?
|
757
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
758
|
+
end
|
759
|
+
end
|
760
|
+
end
|
761
|
+
end
|
762
|
+
|
763
|
+
context "when multiple scopes are provided" do
|
764
|
+
|
765
|
+
before do
|
766
|
+
Dictionary.validates_uniqueness_of :name, scope: [ :publisher, :year ]
|
767
|
+
end
|
768
|
+
|
769
|
+
after do
|
770
|
+
Dictionary.reset_callbacks(:validate)
|
771
|
+
end
|
772
|
+
|
773
|
+
context "when the attribute is unique" do
|
774
|
+
|
775
|
+
before do
|
776
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
777
|
+
end
|
778
|
+
|
779
|
+
let(:dictionary) do
|
780
|
+
Dictionary.new(name: "Webster")
|
781
|
+
end
|
782
|
+
|
783
|
+
it "returns true" do
|
784
|
+
expect(dictionary).to be_valid
|
785
|
+
end
|
786
|
+
end
|
787
|
+
|
788
|
+
context "when the attribute is unique in the scope" do
|
789
|
+
|
790
|
+
before do
|
791
|
+
Dictionary.create(
|
792
|
+
name: "Oxford",
|
793
|
+
publisher: "Amazon",
|
794
|
+
year: 2011
|
795
|
+
)
|
796
|
+
end
|
797
|
+
|
798
|
+
let(:dictionary) do
|
799
|
+
Dictionary.new(
|
800
|
+
name: "Webster",
|
801
|
+
publisher: "Amazon",
|
802
|
+
year: 2011
|
803
|
+
)
|
804
|
+
end
|
805
|
+
|
806
|
+
it "returns true" do
|
807
|
+
expect(dictionary).to be_valid
|
808
|
+
end
|
809
|
+
end
|
810
|
+
|
811
|
+
context "when the attribute is not unique with no scope" do
|
812
|
+
|
813
|
+
before do
|
814
|
+
Dictionary.create(name: "Oxford", publisher: "Amazon")
|
815
|
+
end
|
816
|
+
|
817
|
+
let(:dictionary) do
|
818
|
+
Dictionary.new(name: "Oxford")
|
819
|
+
end
|
820
|
+
|
821
|
+
it "returns true" do
|
822
|
+
expect(dictionary).to be_valid
|
823
|
+
end
|
824
|
+
end
|
825
|
+
|
826
|
+
context "when the attribute is not unique in another scope" do
|
827
|
+
|
828
|
+
before do
|
829
|
+
Dictionary.create(
|
830
|
+
name: "Oxford",
|
831
|
+
publisher: "Amazon",
|
832
|
+
year: 1995
|
833
|
+
)
|
834
|
+
end
|
835
|
+
|
836
|
+
let(:dictionary) do
|
837
|
+
Dictionary.new(
|
838
|
+
name: "Oxford",
|
839
|
+
publisher: "Addison",
|
840
|
+
year: 2011
|
841
|
+
)
|
842
|
+
end
|
843
|
+
|
844
|
+
it "returns true" do
|
845
|
+
expect(dictionary).to be_valid
|
846
|
+
end
|
847
|
+
end
|
848
|
+
|
849
|
+
context "when the attribute is not unique in the same scope" do
|
850
|
+
|
851
|
+
context "when the document is not the match" do
|
852
|
+
|
853
|
+
before do
|
854
|
+
Dictionary.create(
|
855
|
+
name: "Oxford",
|
856
|
+
publisher: "Amazon",
|
857
|
+
year: 1960
|
858
|
+
)
|
859
|
+
end
|
860
|
+
|
861
|
+
let(:dictionary) do
|
862
|
+
Dictionary.new(
|
863
|
+
name: "Oxford",
|
864
|
+
publisher: "Amazon",
|
865
|
+
year: 1960
|
866
|
+
)
|
867
|
+
end
|
868
|
+
|
869
|
+
it "returns false" do
|
870
|
+
expect(dictionary).to_not be_valid
|
871
|
+
end
|
872
|
+
|
873
|
+
it "adds the uniqueness errors" do
|
874
|
+
dictionary.valid?
|
875
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
876
|
+
end
|
877
|
+
end
|
878
|
+
|
879
|
+
context "when the document is the match in the database" do
|
880
|
+
|
881
|
+
let!(:dictionary) do
|
882
|
+
Dictionary.create(
|
883
|
+
name: "Oxford",
|
884
|
+
publisher: "Amazon",
|
885
|
+
year: 1960
|
886
|
+
)
|
887
|
+
end
|
888
|
+
|
889
|
+
it "returns true" do
|
890
|
+
expect(dictionary).to be_valid
|
891
|
+
end
|
892
|
+
end
|
893
|
+
end
|
894
|
+
end
|
895
|
+
|
896
|
+
context "when case sensitive is true" do
|
897
|
+
|
898
|
+
before do
|
899
|
+
Dictionary.validates_uniqueness_of :name
|
900
|
+
end
|
901
|
+
|
902
|
+
after do
|
903
|
+
Dictionary.reset_callbacks(:validate)
|
904
|
+
end
|
905
|
+
|
906
|
+
context "when the attribute is unique" do
|
907
|
+
|
908
|
+
before do
|
909
|
+
Dictionary.create(name: "Oxford")
|
910
|
+
end
|
911
|
+
|
912
|
+
let(:dictionary) do
|
913
|
+
Dictionary.new(name: "Webster")
|
914
|
+
end
|
915
|
+
|
916
|
+
it "returns true" do
|
917
|
+
expect(dictionary).to be_valid
|
918
|
+
end
|
919
|
+
end
|
920
|
+
|
921
|
+
context "when the attribute is not unique" do
|
922
|
+
|
923
|
+
context "when the document is not the match" do
|
924
|
+
|
925
|
+
before do
|
926
|
+
Dictionary.create(name: "Oxford")
|
927
|
+
end
|
928
|
+
|
929
|
+
let(:dictionary) do
|
930
|
+
Dictionary.new(name: "Oxford")
|
931
|
+
end
|
932
|
+
|
933
|
+
it "returns false" do
|
934
|
+
expect(dictionary).to_not be_valid
|
935
|
+
end
|
936
|
+
|
937
|
+
it "adds the uniqueness error" do
|
938
|
+
dictionary.valid?
|
939
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
context "when the document is the match in the database" do
|
944
|
+
|
945
|
+
let!(:dictionary) do
|
946
|
+
Dictionary.create(name: "Oxford")
|
947
|
+
end
|
948
|
+
|
949
|
+
it "returns true" do
|
950
|
+
expect(dictionary).to be_valid
|
951
|
+
end
|
952
|
+
end
|
953
|
+
end
|
954
|
+
end
|
955
|
+
|
956
|
+
context "when case sensitive is false" do
|
957
|
+
|
958
|
+
before do
|
959
|
+
Dictionary.validates_uniqueness_of :name, case_sensitive: false
|
960
|
+
end
|
961
|
+
|
962
|
+
after do
|
963
|
+
Dictionary.reset_callbacks(:validate)
|
964
|
+
end
|
965
|
+
|
966
|
+
context "when the attribute is unique" do
|
967
|
+
|
968
|
+
context "when there are no special characters" do
|
969
|
+
|
970
|
+
before do
|
971
|
+
Dictionary.create(name: "Oxford")
|
972
|
+
end
|
973
|
+
|
974
|
+
let(:dictionary) do
|
975
|
+
Dictionary.new(name: "Webster")
|
976
|
+
end
|
977
|
+
|
978
|
+
it "returns true" do
|
979
|
+
expect(dictionary).to be_valid
|
980
|
+
end
|
981
|
+
end
|
982
|
+
|
983
|
+
context "when special characters exist" do
|
984
|
+
|
985
|
+
before do
|
986
|
+
Dictionary.create(name: "Oxford")
|
987
|
+
end
|
988
|
+
|
989
|
+
let(:dictionary) do
|
990
|
+
Dictionary.new(name: "Web@st.er")
|
991
|
+
end
|
992
|
+
|
993
|
+
it "returns true" do
|
994
|
+
expect(dictionary).to be_valid
|
995
|
+
end
|
996
|
+
end
|
997
|
+
end
|
998
|
+
|
999
|
+
context "when the attribute is not unique" do
|
1000
|
+
|
1001
|
+
context "when the document is not the match" do
|
1002
|
+
|
1003
|
+
before do
|
1004
|
+
Dictionary.create(name: "Oxford")
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
let(:dictionary) do
|
1008
|
+
Dictionary.new(name: "oxford")
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
it "returns false" do
|
1012
|
+
expect(dictionary).to_not be_valid
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it "adds the uniqueness error" do
|
1016
|
+
dictionary.valid?
|
1017
|
+
expect(dictionary.errors[:name]).to eq([ "is already taken" ])
|
1018
|
+
end
|
1019
|
+
end
|
1020
|
+
|
1021
|
+
context "when the document is the match in the database" do
|
1022
|
+
|
1023
|
+
let!(:dictionary) do
|
1024
|
+
Dictionary.create(name: "Oxford")
|
1025
|
+
end
|
1026
|
+
|
1027
|
+
it "returns true" do
|
1028
|
+
expect(dictionary).to be_valid
|
1029
|
+
end
|
1030
|
+
end
|
1031
|
+
end
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
context "when allowing nil" do
|
1035
|
+
|
1036
|
+
before do
|
1037
|
+
Dictionary.validates_uniqueness_of :name, allow_nil: true
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
after do
|
1041
|
+
Dictionary.reset_callbacks(:validate)
|
1042
|
+
end
|
1043
|
+
|
1044
|
+
context "when the attribute is nil" do
|
1045
|
+
|
1046
|
+
before do
|
1047
|
+
Dictionary.create
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
let(:dictionary) do
|
1051
|
+
Dictionary.new
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
it "returns true" do
|
1055
|
+
expect(dictionary).to be_valid
|
1056
|
+
end
|
1057
|
+
end
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
context "when allowing blank" do
|
1061
|
+
|
1062
|
+
before do
|
1063
|
+
Dictionary.validates_uniqueness_of :name, allow_blank: true
|
1064
|
+
end
|
1065
|
+
|
1066
|
+
after do
|
1067
|
+
Dictionary.reset_callbacks(:validate)
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
context "when the attribute is blank" do
|
1071
|
+
|
1072
|
+
before do
|
1073
|
+
Dictionary.create(name: "")
|
1074
|
+
end
|
1075
|
+
|
1076
|
+
let(:dictionary) do
|
1077
|
+
Dictionary.new(name: "")
|
1078
|
+
end
|
1079
|
+
|
1080
|
+
it "returns true" do
|
1081
|
+
expect(dictionary).to be_valid
|
1082
|
+
end
|
1083
|
+
end
|
1084
|
+
end
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
context "when the document contains a compound key" do
|
1088
|
+
|
1089
|
+
context "when no scope is provided" do
|
1090
|
+
|
1091
|
+
before do
|
1092
|
+
Login.validates_uniqueness_of :username
|
1093
|
+
end
|
1094
|
+
|
1095
|
+
after do
|
1096
|
+
Login.reset_callbacks(:validate)
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
context "when the attribute is unique" do
|
1100
|
+
|
1101
|
+
before do
|
1102
|
+
Login.create(username: "Oxford")
|
1103
|
+
end
|
1104
|
+
|
1105
|
+
let(:login) do
|
1106
|
+
Login.new(username: "Webster")
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
it "returns true" do
|
1110
|
+
expect(login).to be_valid
|
1111
|
+
end
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
context "when the attribute is not unique" do
|
1115
|
+
|
1116
|
+
context "when the document is not the match" do
|
1117
|
+
|
1118
|
+
before do
|
1119
|
+
Login.create(username: "Oxford")
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
let(:login) do
|
1123
|
+
Login.new(username: "Oxford")
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
it "returns false" do
|
1127
|
+
expect(login).to_not be_valid
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
it "adds the uniqueness error" do
|
1131
|
+
login.valid?
|
1132
|
+
expect(login.errors[:username]).to eq([ "is already taken" ])
|
1133
|
+
end
|
1134
|
+
end
|
1135
|
+
|
1136
|
+
context "when the document is the match in the database" do
|
1137
|
+
|
1138
|
+
let!(:login) do
|
1139
|
+
Login.create(username: "Oxford")
|
1140
|
+
end
|
1141
|
+
|
1142
|
+
it "returns true" do
|
1143
|
+
expect(login).to be_valid
|
1144
|
+
end
|
1145
|
+
end
|
1146
|
+
end
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
context "when a single scope is provided" do
|
1150
|
+
|
1151
|
+
before do
|
1152
|
+
Login.validates_uniqueness_of :username, scope: :application_id
|
1153
|
+
end
|
1154
|
+
|
1155
|
+
after do
|
1156
|
+
Login.reset_callbacks(:validate)
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
context "when the attribute is unique" do
|
1160
|
+
|
1161
|
+
before do
|
1162
|
+
Login.create(username: "Oxford", application_id: 1)
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
let(:login) do
|
1166
|
+
Login.new(username: "Webster")
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
it "returns true" do
|
1170
|
+
expect(login).to be_valid
|
1171
|
+
end
|
1172
|
+
end
|
1173
|
+
|
1174
|
+
context "when the attribute is unique in the scope" do
|
1175
|
+
|
1176
|
+
before do
|
1177
|
+
Login.create(username: "Oxford", application_id: 1)
|
1178
|
+
end
|
1179
|
+
|
1180
|
+
let(:login) do
|
1181
|
+
Login.new(username: "Webster", application_id: 1)
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
it "returns true" do
|
1185
|
+
expect(login).to be_valid
|
1186
|
+
end
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
context "when the attribute is not unique with no scope" do
|
1190
|
+
|
1191
|
+
before do
|
1192
|
+
Login.create(username: "Oxford", application_id: 1)
|
1193
|
+
end
|
1194
|
+
|
1195
|
+
let(:login) do
|
1196
|
+
Login.new(username: "Oxford")
|
1197
|
+
end
|
1198
|
+
|
1199
|
+
it "returns true" do
|
1200
|
+
expect(login).to be_valid
|
1201
|
+
end
|
1202
|
+
end
|
1203
|
+
|
1204
|
+
context "when the attribute is not unique in another scope" do
|
1205
|
+
|
1206
|
+
before do
|
1207
|
+
Login.create(username: "Oxford", application_id: 1)
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
let(:login) do
|
1211
|
+
Login.new(username: "Oxford", application_id: 2)
|
1212
|
+
end
|
1213
|
+
|
1214
|
+
it "returns true" do
|
1215
|
+
expect(login).to be_valid
|
1216
|
+
end
|
1217
|
+
end
|
1218
|
+
|
1219
|
+
context "when the attribute is not unique in the same scope" do
|
1220
|
+
|
1221
|
+
context "when the document is not the match" do
|
1222
|
+
|
1223
|
+
before do
|
1224
|
+
Login.create(username: "Oxford", application_id: 1)
|
1225
|
+
end
|
1226
|
+
|
1227
|
+
let(:login) do
|
1228
|
+
Login.new(username: "Oxford", application_id: 1)
|
1229
|
+
end
|
1230
|
+
|
1231
|
+
it "returns false" do
|
1232
|
+
expect(login).to_not be_valid
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
it "adds the uniqueness errors" do
|
1236
|
+
login.valid?
|
1237
|
+
expect(login.errors[:username]).to eq([ "is already taken" ])
|
1238
|
+
end
|
1239
|
+
end
|
1240
|
+
|
1241
|
+
context "when the document is the match in the database" do
|
1242
|
+
|
1243
|
+
let!(:login) do
|
1244
|
+
Login.create(username: "Oxford", application_id: 1)
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
it "returns true" do
|
1248
|
+
expect(login).to be_valid
|
1249
|
+
end
|
1250
|
+
end
|
1251
|
+
end
|
1252
|
+
end
|
1253
|
+
|
1254
|
+
context "when case sensitive is true" do
|
1255
|
+
|
1256
|
+
before do
|
1257
|
+
Login.validates_uniqueness_of :username
|
1258
|
+
end
|
1259
|
+
|
1260
|
+
after do
|
1261
|
+
Login.reset_callbacks(:validate)
|
1262
|
+
end
|
1263
|
+
|
1264
|
+
context "when the attribute is unique" do
|
1265
|
+
|
1266
|
+
before do
|
1267
|
+
Login.create(username: "Oxford")
|
1268
|
+
end
|
1269
|
+
|
1270
|
+
let(:login) do
|
1271
|
+
Login.new(username: "Webster")
|
1272
|
+
end
|
1273
|
+
|
1274
|
+
it "returns true" do
|
1275
|
+
expect(login).to be_valid
|
1276
|
+
end
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
context "when the attribute is not unique" do
|
1280
|
+
|
1281
|
+
context "when the document is not the match" do
|
1282
|
+
|
1283
|
+
before do
|
1284
|
+
Login.create(username: "Oxford")
|
1285
|
+
end
|
1286
|
+
|
1287
|
+
let(:login) do
|
1288
|
+
Login.new(username: "Oxford")
|
1289
|
+
end
|
1290
|
+
|
1291
|
+
it "returns false" do
|
1292
|
+
expect(login).to_not be_valid
|
1293
|
+
end
|
1294
|
+
|
1295
|
+
it "adds the uniqueness error" do
|
1296
|
+
login.valid?
|
1297
|
+
expect(login.errors[:username]).to eq([ "is already taken" ])
|
1298
|
+
end
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
context "when the document is the match in the database" do
|
1302
|
+
|
1303
|
+
let!(:login) do
|
1304
|
+
Login.create(username: "Oxford")
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
it "returns true" do
|
1308
|
+
expect(login).to be_valid
|
1309
|
+
end
|
1310
|
+
end
|
1311
|
+
end
|
1312
|
+
end
|
1313
|
+
|
1314
|
+
context "when case sensitive is false" do
|
1315
|
+
|
1316
|
+
before do
|
1317
|
+
Login.validates_uniqueness_of :username, case_sensitive: false
|
1318
|
+
end
|
1319
|
+
|
1320
|
+
after do
|
1321
|
+
Login.reset_callbacks(:validate)
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
context "when the attribute is unique" do
|
1325
|
+
|
1326
|
+
context "when there are no special characters" do
|
1327
|
+
|
1328
|
+
before do
|
1329
|
+
Login.create(username: "Oxford")
|
1330
|
+
end
|
1331
|
+
|
1332
|
+
let(:login) do
|
1333
|
+
Login.new(username: "Webster")
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
it "returns true" do
|
1337
|
+
expect(login).to be_valid
|
1338
|
+
end
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
context "when special characters exist" do
|
1342
|
+
|
1343
|
+
before do
|
1344
|
+
Login.create(username: "Oxford")
|
1345
|
+
end
|
1346
|
+
|
1347
|
+
let(:login) do
|
1348
|
+
Login.new(username: "Web@st.er")
|
1349
|
+
end
|
1350
|
+
|
1351
|
+
it "returns true" do
|
1352
|
+
expect(login).to be_valid
|
1353
|
+
end
|
1354
|
+
end
|
1355
|
+
end
|
1356
|
+
|
1357
|
+
context "when the attribute is not unique" do
|
1358
|
+
|
1359
|
+
context "when the document is not the match" do
|
1360
|
+
|
1361
|
+
before do
|
1362
|
+
Login.create(username: "Oxford")
|
1363
|
+
end
|
1364
|
+
|
1365
|
+
let(:login) do
|
1366
|
+
Login.new(username: "oxford")
|
1367
|
+
end
|
1368
|
+
|
1369
|
+
it "returns false" do
|
1370
|
+
expect(login).to_not be_valid
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
it "adds the uniqueness error" do
|
1374
|
+
login.valid?
|
1375
|
+
expect(login.errors[:username]).to eq([ "is already taken" ])
|
1376
|
+
end
|
1377
|
+
end
|
1378
|
+
|
1379
|
+
context "when the document is the match in the database" do
|
1380
|
+
|
1381
|
+
let!(:login) do
|
1382
|
+
Login.create(username: "Oxford")
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
it "returns true" do
|
1386
|
+
expect(login).to be_valid
|
1387
|
+
end
|
1388
|
+
end
|
1389
|
+
end
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
context "when allowing nil" do
|
1393
|
+
|
1394
|
+
before do
|
1395
|
+
Login.validates_uniqueness_of :username, allow_nil: true
|
1396
|
+
end
|
1397
|
+
|
1398
|
+
after do
|
1399
|
+
Login.reset_callbacks(:validate)
|
1400
|
+
end
|
1401
|
+
|
1402
|
+
context "when the attribute is nil" do
|
1403
|
+
|
1404
|
+
before do
|
1405
|
+
Login.create
|
1406
|
+
end
|
1407
|
+
|
1408
|
+
let(:login) do
|
1409
|
+
Login.new
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
it "returns true" do
|
1413
|
+
expect(login).to be_valid
|
1414
|
+
end
|
1415
|
+
end
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
context "when allowing blank" do
|
1419
|
+
|
1420
|
+
before do
|
1421
|
+
Login.validates_uniqueness_of :username, allow_blank: true
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
after do
|
1425
|
+
Login.reset_callbacks(:validate)
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
context "when the attribute is blank" do
|
1429
|
+
|
1430
|
+
before do
|
1431
|
+
Login.create(username: "")
|
1432
|
+
end
|
1433
|
+
|
1434
|
+
let(:login) do
|
1435
|
+
Login.new(username: "")
|
1436
|
+
end
|
1437
|
+
|
1438
|
+
it "returns true" do
|
1439
|
+
expect(login).to be_valid
|
1440
|
+
end
|
1441
|
+
end
|
1442
|
+
end
|
1443
|
+
end
|
1444
|
+
|
1445
|
+
context "when the attribute is a custom type" do
|
1446
|
+
|
1447
|
+
before do
|
1448
|
+
Bar.validates_uniqueness_of :lat_lng
|
1449
|
+
end
|
1450
|
+
|
1451
|
+
after do
|
1452
|
+
Bar.reset_callbacks(:validate)
|
1453
|
+
end
|
1454
|
+
|
1455
|
+
context "when the attribute is unique" do
|
1456
|
+
|
1457
|
+
before do
|
1458
|
+
Bar.create(lat_lng: LatLng.new(52.30, 13.25))
|
1459
|
+
end
|
1460
|
+
|
1461
|
+
let(:unique_bar) do
|
1462
|
+
Bar.new(lat_lng: LatLng.new(54.30, 14.25))
|
1463
|
+
end
|
1464
|
+
|
1465
|
+
it "returns true" do
|
1466
|
+
expect(unique_bar).to be_valid
|
1467
|
+
end
|
1468
|
+
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
context "when the attribute is not unique" do
|
1472
|
+
|
1473
|
+
before do
|
1474
|
+
Bar.create(lat_lng: LatLng.new(52.30, 13.25))
|
1475
|
+
end
|
1476
|
+
|
1477
|
+
let(:non_unique_bar) do
|
1478
|
+
Bar.new(lat_lng: LatLng.new(52.30, 13.25))
|
1479
|
+
end
|
1480
|
+
|
1481
|
+
it "returns false" do
|
1482
|
+
expect(non_unique_bar).to_not be_valid
|
1483
|
+
end
|
1484
|
+
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
end
|
1488
|
+
end
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
context "when the document is embedded" do
|
1492
|
+
|
1493
|
+
let(:word) do
|
1494
|
+
Word.create(name: "Schadenfreude")
|
1495
|
+
end
|
1496
|
+
|
1497
|
+
context "when in an embeds_many" do
|
1498
|
+
|
1499
|
+
let!(:def_one) do
|
1500
|
+
word.definitions.create(description: "1")
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
let!(:def_two) do
|
1504
|
+
word.definitions.create(description: "2")
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
context "when a document is being destroyed" do
|
1508
|
+
|
1509
|
+
before do
|
1510
|
+
Definition.validates_uniqueness_of :description
|
1511
|
+
end
|
1512
|
+
|
1513
|
+
after do
|
1514
|
+
Definition.reset_callbacks(:validate)
|
1515
|
+
end
|
1516
|
+
|
1517
|
+
context "when changing a document to the destroyed property" do
|
1518
|
+
|
1519
|
+
let(:attributes) do
|
1520
|
+
{
|
1521
|
+
definitions_attributes: {
|
1522
|
+
"0" => { id: def_one.id, description: "0", "_destroy" => 1 },
|
1523
|
+
"1" => { id: def_two.id, description: "1" }
|
1524
|
+
}
|
1525
|
+
}
|
1526
|
+
end
|
1527
|
+
|
1528
|
+
before do
|
1529
|
+
word.attributes = attributes
|
1530
|
+
end
|
1531
|
+
|
1532
|
+
it "returns true" do
|
1533
|
+
expect(def_two).to be_valid
|
1534
|
+
end
|
1535
|
+
end
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
context "when the document does not use composite keys" do
|
1539
|
+
|
1540
|
+
context "when no scope is provided" do
|
1541
|
+
|
1542
|
+
before do
|
1543
|
+
Definition.validates_uniqueness_of :description
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
after do
|
1547
|
+
Definition.reset_callbacks(:validate)
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
context "when the attribute is unique" do
|
1551
|
+
|
1552
|
+
before do
|
1553
|
+
word.definitions.build(description: "Malicious joy")
|
1554
|
+
end
|
1555
|
+
|
1556
|
+
let(:definition) do
|
1557
|
+
word.definitions.build(description: "Gloating")
|
1558
|
+
end
|
1559
|
+
|
1560
|
+
it "returns true" do
|
1561
|
+
expect(definition).to be_valid
|
1562
|
+
end
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
context "when the attribute is not unique" do
|
1566
|
+
|
1567
|
+
context "when the document is not the match" do
|
1568
|
+
|
1569
|
+
before do
|
1570
|
+
word.definitions.build(description: "Malicious joy")
|
1571
|
+
end
|
1572
|
+
|
1573
|
+
let(:definition) do
|
1574
|
+
word.definitions.build(description: "Malicious joy")
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
it "returns false" do
|
1578
|
+
expect(definition).to_not be_valid
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
it "adds the uniqueness error" do
|
1582
|
+
definition.valid?
|
1583
|
+
expect(definition.errors[:description]).to eq([ "is already taken" ])
|
1584
|
+
end
|
1585
|
+
end
|
1586
|
+
|
1587
|
+
context "when the document is the match in the database" do
|
1588
|
+
|
1589
|
+
let!(:definition) do
|
1590
|
+
word.definitions.build(description: "Malicious joy")
|
1591
|
+
end
|
1592
|
+
|
1593
|
+
it "returns true" do
|
1594
|
+
expect(definition).to be_valid
|
1595
|
+
end
|
1596
|
+
end
|
1597
|
+
end
|
1598
|
+
end
|
1599
|
+
|
1600
|
+
context "when a single scope is provided" do
|
1601
|
+
|
1602
|
+
before do
|
1603
|
+
Definition.validates_uniqueness_of :description, scope: :part
|
1604
|
+
end
|
1605
|
+
|
1606
|
+
after do
|
1607
|
+
Definition.reset_callbacks(:validate)
|
1608
|
+
end
|
1609
|
+
|
1610
|
+
context "when the attribute is unique" do
|
1611
|
+
|
1612
|
+
before do
|
1613
|
+
word.definitions.build(
|
1614
|
+
description: "Malicious joy", part: "Noun"
|
1615
|
+
)
|
1616
|
+
end
|
1617
|
+
|
1618
|
+
let(:definition) do
|
1619
|
+
word.definitions.build(description: "Gloating")
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
it "returns true" do
|
1623
|
+
expect(definition).to be_valid
|
1624
|
+
end
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
context "when the attribute is unique in the scope" do
|
1628
|
+
|
1629
|
+
before do
|
1630
|
+
word.definitions.build(
|
1631
|
+
description: "Malicious joy",
|
1632
|
+
part: "Noun"
|
1633
|
+
)
|
1634
|
+
end
|
1635
|
+
|
1636
|
+
let(:definition) do
|
1637
|
+
word.definitions.build(
|
1638
|
+
description: "Gloating",
|
1639
|
+
part: "Noun"
|
1640
|
+
)
|
1641
|
+
end
|
1642
|
+
|
1643
|
+
it "returns true" do
|
1644
|
+
expect(definition).to be_valid
|
1645
|
+
end
|
1646
|
+
end
|
1647
|
+
|
1648
|
+
context "when the attribute is not unique with no scope" do
|
1649
|
+
|
1650
|
+
before do
|
1651
|
+
word.definitions.build(
|
1652
|
+
description: "Malicious joy",
|
1653
|
+
part: "Noun"
|
1654
|
+
)
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
let(:definition) do
|
1658
|
+
word.definitions.build(description: "Malicious joy")
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
it "returns true" do
|
1662
|
+
expect(definition).to be_valid
|
1663
|
+
end
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
context "when the attribute is not unique in another scope" do
|
1667
|
+
|
1668
|
+
before do
|
1669
|
+
word.definitions.build(
|
1670
|
+
description: "Malicious joy",
|
1671
|
+
part: "Noun"
|
1672
|
+
)
|
1673
|
+
end
|
1674
|
+
|
1675
|
+
let(:definition) do
|
1676
|
+
word.definitions.build(
|
1677
|
+
description: "Malicious joy",
|
1678
|
+
part: "Adj"
|
1679
|
+
)
|
1680
|
+
end
|
1681
|
+
|
1682
|
+
it "returns true" do
|
1683
|
+
expect(definition).to be_valid
|
1684
|
+
end
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
context "when the attribute is not unique in the same scope" do
|
1688
|
+
|
1689
|
+
context "when the document is not the match" do
|
1690
|
+
|
1691
|
+
before do
|
1692
|
+
word.definitions.build(
|
1693
|
+
description: "Malicious joy",
|
1694
|
+
part: "Noun"
|
1695
|
+
)
|
1696
|
+
end
|
1697
|
+
|
1698
|
+
let(:definition) do
|
1699
|
+
word.definitions.build(
|
1700
|
+
description: "Malicious joy",
|
1701
|
+
part: "Noun"
|
1702
|
+
)
|
1703
|
+
end
|
1704
|
+
|
1705
|
+
it "returns false" do
|
1706
|
+
expect(definition).to_not be_valid
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
it "adds the uniqueness errors" do
|
1710
|
+
definition.valid?
|
1711
|
+
expect(definition.errors[:description]).to eq([ "is already taken" ])
|
1712
|
+
end
|
1713
|
+
end
|
1714
|
+
|
1715
|
+
context "when the document is the match in the database" do
|
1716
|
+
|
1717
|
+
let!(:definition) do
|
1718
|
+
word.definitions.build(
|
1719
|
+
description: "Malicious joy",
|
1720
|
+
part: "Noun"
|
1721
|
+
)
|
1722
|
+
end
|
1723
|
+
|
1724
|
+
it "returns true" do
|
1725
|
+
expect(definition).to be_valid
|
1726
|
+
end
|
1727
|
+
end
|
1728
|
+
end
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
context "when multiple scopes are provided" do
|
1732
|
+
|
1733
|
+
before do
|
1734
|
+
Definition.validates_uniqueness_of :description, scope: [ :part, :regular ]
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
after do
|
1738
|
+
Definition.reset_callbacks(:validate)
|
1739
|
+
end
|
1740
|
+
|
1741
|
+
context "when the attribute is unique" do
|
1742
|
+
|
1743
|
+
before do
|
1744
|
+
word.definitions.build(
|
1745
|
+
description: "Malicious joy",
|
1746
|
+
part: "Noun"
|
1747
|
+
)
|
1748
|
+
end
|
1749
|
+
|
1750
|
+
let(:definition) do
|
1751
|
+
word.definitions.build(description: "Gloating")
|
1752
|
+
end
|
1753
|
+
|
1754
|
+
it "returns true" do
|
1755
|
+
expect(definition).to be_valid
|
1756
|
+
end
|
1757
|
+
end
|
1758
|
+
|
1759
|
+
context "when the attribute is unique in the scope" do
|
1760
|
+
|
1761
|
+
before do
|
1762
|
+
word.definitions.build(
|
1763
|
+
description: "Malicious joy",
|
1764
|
+
part: "Noun",
|
1765
|
+
regular: true
|
1766
|
+
)
|
1767
|
+
end
|
1768
|
+
|
1769
|
+
let(:definition) do
|
1770
|
+
word.definitions.build(
|
1771
|
+
description: "Gloating",
|
1772
|
+
part: "Noun",
|
1773
|
+
regular: true
|
1774
|
+
)
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
it "returns true" do
|
1778
|
+
expect(definition).to be_valid
|
1779
|
+
end
|
1780
|
+
end
|
1781
|
+
|
1782
|
+
context "when the attribute is not unique with no scope" do
|
1783
|
+
|
1784
|
+
before do
|
1785
|
+
word.definitions.build(
|
1786
|
+
description: "Malicious joy",
|
1787
|
+
part: "Noun"
|
1788
|
+
)
|
1789
|
+
end
|
1790
|
+
|
1791
|
+
let(:definition) do
|
1792
|
+
word.definitions.build(description: "Malicious scope")
|
1793
|
+
end
|
1794
|
+
|
1795
|
+
it "returns true" do
|
1796
|
+
expect(definition).to be_valid
|
1797
|
+
end
|
1798
|
+
end
|
1799
|
+
|
1800
|
+
context "when the attribute is not unique in another scope" do
|
1801
|
+
|
1802
|
+
before do
|
1803
|
+
word.definitions.build(
|
1804
|
+
description: "Malicious joy",
|
1805
|
+
part: "Noun",
|
1806
|
+
regular: true
|
1807
|
+
)
|
1808
|
+
end
|
1809
|
+
|
1810
|
+
let(:definition) do
|
1811
|
+
word.definitions.build(
|
1812
|
+
description: "Malicious joy",
|
1813
|
+
part: "Adj",
|
1814
|
+
regular: true
|
1815
|
+
)
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
it "returns true" do
|
1819
|
+
expect(definition).to be_valid
|
1820
|
+
end
|
1821
|
+
end
|
1822
|
+
|
1823
|
+
context "when the attribute is not unique in the same scope" do
|
1824
|
+
|
1825
|
+
context "when the document is not the match" do
|
1826
|
+
|
1827
|
+
before do
|
1828
|
+
word.definitions.build(
|
1829
|
+
description: "Malicious joy",
|
1830
|
+
part: "Noun",
|
1831
|
+
regular: true
|
1832
|
+
)
|
1833
|
+
end
|
1834
|
+
|
1835
|
+
let(:definition) do
|
1836
|
+
word.definitions.build(
|
1837
|
+
description: "Malicious joy",
|
1838
|
+
part: "Noun",
|
1839
|
+
regular: true
|
1840
|
+
)
|
1841
|
+
end
|
1842
|
+
|
1843
|
+
it "returns false" do
|
1844
|
+
expect(definition).to_not be_valid
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
it "adds the uniqueness errors" do
|
1848
|
+
definition.valid?
|
1849
|
+
expect(definition.errors[:description]).to eq([ "is already taken" ])
|
1850
|
+
end
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
context "when the document is the match in the database" do
|
1854
|
+
|
1855
|
+
let!(:definition) do
|
1856
|
+
word.definitions.build(
|
1857
|
+
description: "Malicious joy",
|
1858
|
+
part: "Noun",
|
1859
|
+
regular: false
|
1860
|
+
)
|
1861
|
+
end
|
1862
|
+
|
1863
|
+
it "returns true" do
|
1864
|
+
expect(definition).to be_valid
|
1865
|
+
end
|
1866
|
+
end
|
1867
|
+
end
|
1868
|
+
end
|
1869
|
+
|
1870
|
+
context "when case sensitive is true" do
|
1871
|
+
|
1872
|
+
before do
|
1873
|
+
Definition.validates_uniqueness_of :description
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
after do
|
1877
|
+
Definition.reset_callbacks(:validate)
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
context "when the attribute is unique" do
|
1881
|
+
|
1882
|
+
before do
|
1883
|
+
word.definitions.build(description: "Malicious jo")
|
1884
|
+
end
|
1885
|
+
|
1886
|
+
let(:definition) do
|
1887
|
+
word.definitions.build(description: "Gloating")
|
1888
|
+
end
|
1889
|
+
|
1890
|
+
it "returns true" do
|
1891
|
+
expect(definition).to be_valid
|
1892
|
+
end
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
context "when the attribute is not unique" do
|
1896
|
+
|
1897
|
+
context "when the document is not the match" do
|
1898
|
+
|
1899
|
+
before do
|
1900
|
+
word.definitions.build(description: "Malicious joy")
|
1901
|
+
end
|
1902
|
+
|
1903
|
+
let(:definition) do
|
1904
|
+
word.definitions.build(description: "Malicious joy")
|
1905
|
+
end
|
1906
|
+
|
1907
|
+
it "returns false" do
|
1908
|
+
expect(definition).to_not be_valid
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
it "adds the uniqueness error" do
|
1912
|
+
definition.valid?
|
1913
|
+
expect(definition.errors[:description]).to eq([ "is already taken" ])
|
1914
|
+
end
|
1915
|
+
end
|
1916
|
+
|
1917
|
+
context "when the document is the match in the database" do
|
1918
|
+
|
1919
|
+
let!(:definition) do
|
1920
|
+
word.definitions.build(description: "Malicious joy")
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
it "returns true" do
|
1924
|
+
expect(definition).to be_valid
|
1925
|
+
end
|
1926
|
+
end
|
1927
|
+
end
|
1928
|
+
end
|
1929
|
+
|
1930
|
+
context "when case sensitive is false" do
|
1931
|
+
|
1932
|
+
before do
|
1933
|
+
Definition.validates_uniqueness_of :description, case_sensitive: false
|
1934
|
+
end
|
1935
|
+
|
1936
|
+
after do
|
1937
|
+
Definition.reset_callbacks(:validate)
|
1938
|
+
end
|
1939
|
+
|
1940
|
+
context "when the attribute is unique" do
|
1941
|
+
|
1942
|
+
context "when there are no special characters" do
|
1943
|
+
|
1944
|
+
before do
|
1945
|
+
word.definitions.build(description: "Malicious joy")
|
1946
|
+
end
|
1947
|
+
|
1948
|
+
let(:definition) do
|
1949
|
+
word.definitions.build(description: "Gloating")
|
1950
|
+
end
|
1951
|
+
|
1952
|
+
it "returns true" do
|
1953
|
+
expect(definition).to be_valid
|
1954
|
+
end
|
1955
|
+
end
|
1956
|
+
|
1957
|
+
context "when special characters exist" do
|
1958
|
+
|
1959
|
+
before do
|
1960
|
+
word.definitions.build(description: "Malicious joy")
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
let(:definition) do
|
1964
|
+
word.definitions.build(description: "M@licious.joy")
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
it "returns true" do
|
1968
|
+
expect(definition).to be_valid
|
1969
|
+
end
|
1970
|
+
end
|
1971
|
+
end
|
1972
|
+
|
1973
|
+
context "when the attribute is not unique" do
|
1974
|
+
|
1975
|
+
context "when the document is not the match" do
|
1976
|
+
|
1977
|
+
before do
|
1978
|
+
word.definitions.build(description: "Malicious joy")
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
let(:definition) do
|
1982
|
+
word.definitions.build(description: "Malicious JOY")
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
it "returns false" do
|
1986
|
+
expect(definition).to_not be_valid
|
1987
|
+
end
|
1988
|
+
|
1989
|
+
it "adds the uniqueness error" do
|
1990
|
+
definition.valid?
|
1991
|
+
expect(definition.errors[:description]).to eq([ "is already taken" ])
|
1992
|
+
end
|
1993
|
+
end
|
1994
|
+
|
1995
|
+
context "when the document is the match in the database" do
|
1996
|
+
|
1997
|
+
let!(:definition) do
|
1998
|
+
word.definitions.build(description: "Malicious joy")
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
it "returns true" do
|
2002
|
+
expect(definition).to be_valid
|
2003
|
+
end
|
2004
|
+
end
|
2005
|
+
end
|
2006
|
+
end
|
2007
|
+
|
2008
|
+
context "when allowing nil" do
|
2009
|
+
|
2010
|
+
before do
|
2011
|
+
Definition.validates_uniqueness_of :description, allow_nil: true
|
2012
|
+
end
|
2013
|
+
|
2014
|
+
after do
|
2015
|
+
Definition.reset_callbacks(:validate)
|
2016
|
+
end
|
2017
|
+
|
2018
|
+
context "when the attribute is nil" do
|
2019
|
+
|
2020
|
+
before do
|
2021
|
+
word.definitions.build
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
let(:definition) do
|
2025
|
+
word.definitions.build
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
it "returns true" do
|
2029
|
+
expect(definition).to be_valid
|
2030
|
+
end
|
2031
|
+
end
|
2032
|
+
end
|
2033
|
+
|
2034
|
+
context "when allowing blank" do
|
2035
|
+
|
2036
|
+
before do
|
2037
|
+
Definition.validates_uniqueness_of :description, allow_blank: true
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
after do
|
2041
|
+
Definition.reset_callbacks(:validate)
|
2042
|
+
end
|
2043
|
+
|
2044
|
+
context "when the attribute is blank" do
|
2045
|
+
|
2046
|
+
before do
|
2047
|
+
word.definitions.build(description: "")
|
2048
|
+
end
|
2049
|
+
|
2050
|
+
let(:definition) do
|
2051
|
+
word.definitions.build(description: "")
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
it "returns true" do
|
2055
|
+
expect(definition).to be_valid
|
2056
|
+
end
|
2057
|
+
end
|
2058
|
+
end
|
2059
|
+
|
2060
|
+
context "when the field name is aliased" do
|
2061
|
+
|
2062
|
+
before do
|
2063
|
+
word.definitions.build(part: "noun")
|
2064
|
+
end
|
2065
|
+
|
2066
|
+
let(:definition) do
|
2067
|
+
word.definitions.build(part: "noun")
|
2068
|
+
end
|
2069
|
+
|
2070
|
+
after do
|
2071
|
+
Definition.reset_callbacks(:validate)
|
2072
|
+
end
|
2073
|
+
|
2074
|
+
context "when the validation uses the aliased name" do
|
2075
|
+
|
2076
|
+
before do
|
2077
|
+
Definition.validates_uniqueness_of :part, case_sensitive: false
|
2078
|
+
end
|
2079
|
+
|
2080
|
+
it "correctly detects a uniqueness conflict" do
|
2081
|
+
expect(definition).to_not be_valid
|
2082
|
+
end
|
2083
|
+
|
2084
|
+
it "adds the uniqueness error to the aliased field name" do
|
2085
|
+
definition.valid?
|
2086
|
+
expect(definition.errors).to have_key(:part)
|
2087
|
+
expect(definition.errors[:part]).to eq([ "is already taken" ])
|
2088
|
+
end
|
2089
|
+
end
|
2090
|
+
|
2091
|
+
context "when the validation uses the underlying field name" do
|
2092
|
+
|
2093
|
+
before do
|
2094
|
+
Definition.validates_uniqueness_of :p, case_sensitive: false
|
2095
|
+
end
|
2096
|
+
|
2097
|
+
it "correctly detects a uniqueness conflict" do
|
2098
|
+
expect(definition).to_not be_valid
|
2099
|
+
end
|
2100
|
+
|
2101
|
+
it "adds the uniqueness error to the underlying field name" do
|
2102
|
+
definition.valid?
|
2103
|
+
expect(definition.errors).to have_key(:p)
|
2104
|
+
expect(definition.errors[:p]).to eq([ "is already taken" ])
|
2105
|
+
end
|
2106
|
+
end
|
2107
|
+
end
|
2108
|
+
end
|
2109
|
+
|
2110
|
+
context "when the document uses composite keys" do
|
2111
|
+
|
2112
|
+
context "when no scope is provided" do
|
2113
|
+
|
2114
|
+
before do
|
2115
|
+
WordOrigin.validates_uniqueness_of :origin_id
|
2116
|
+
end
|
2117
|
+
|
2118
|
+
after do
|
2119
|
+
WordOrigin.reset_callbacks(:validate)
|
2120
|
+
end
|
2121
|
+
|
2122
|
+
context "when the attribute is unique" do
|
2123
|
+
|
2124
|
+
before do
|
2125
|
+
word.word_origins.build(origin_id: 1)
|
2126
|
+
end
|
2127
|
+
|
2128
|
+
let(:word_origin) do
|
2129
|
+
word.word_origins.build(origin_id: 2)
|
2130
|
+
end
|
2131
|
+
|
2132
|
+
it "returns true" do
|
2133
|
+
expect(word_origin).to be_valid
|
2134
|
+
end
|
2135
|
+
end
|
2136
|
+
|
2137
|
+
context "when the attribute is not unique" do
|
2138
|
+
|
2139
|
+
context "when the document is not the match" do
|
2140
|
+
|
2141
|
+
before do
|
2142
|
+
word.word_origins.build(origin_id: 1)
|
2143
|
+
end
|
2144
|
+
|
2145
|
+
let(:word_origin) do
|
2146
|
+
word.word_origins.build(origin_id: 1)
|
2147
|
+
end
|
2148
|
+
|
2149
|
+
it "returns false" do
|
2150
|
+
expect(word_origin).to_not be_valid
|
2151
|
+
end
|
2152
|
+
|
2153
|
+
it "adds the uniqueness error" do
|
2154
|
+
word_origin.valid?
|
2155
|
+
expect(word_origin.errors[:origin_id]).to eq([ "is already taken" ])
|
2156
|
+
end
|
2157
|
+
end
|
2158
|
+
|
2159
|
+
context "when the document is the match in the database" do
|
2160
|
+
|
2161
|
+
let!(:word_origin) do
|
2162
|
+
word.word_origins.build(origin_id: 1)
|
2163
|
+
end
|
2164
|
+
|
2165
|
+
it "returns true" do
|
2166
|
+
expect(word_origin).to be_valid
|
2167
|
+
end
|
2168
|
+
end
|
2169
|
+
end
|
2170
|
+
end
|
2171
|
+
|
2172
|
+
context "when allowing nil" do
|
2173
|
+
|
2174
|
+
before do
|
2175
|
+
WordOrigin.validates_uniqueness_of :origin_id, allow_nil: true
|
2176
|
+
end
|
2177
|
+
|
2178
|
+
after do
|
2179
|
+
WordOrigin.reset_callbacks(:validate)
|
2180
|
+
end
|
2181
|
+
|
2182
|
+
context "when the attribute is nil" do
|
2183
|
+
|
2184
|
+
before do
|
2185
|
+
word.word_origins.build
|
2186
|
+
end
|
2187
|
+
|
2188
|
+
let(:word_origin) do
|
2189
|
+
word.word_origins.build
|
2190
|
+
end
|
2191
|
+
|
2192
|
+
it "returns true" do
|
2193
|
+
expect(word_origin).to be_valid
|
2194
|
+
end
|
2195
|
+
end
|
2196
|
+
end
|
2197
|
+
|
2198
|
+
context "when allowing blank" do
|
2199
|
+
|
2200
|
+
before do
|
2201
|
+
WordOrigin.validates_uniqueness_of :origin_id, allow_blank: true
|
2202
|
+
end
|
2203
|
+
|
2204
|
+
after do
|
2205
|
+
WordOrigin.reset_callbacks(:validate)
|
2206
|
+
end
|
2207
|
+
|
2208
|
+
context "when the attribute is blank" do
|
2209
|
+
|
2210
|
+
before do
|
2211
|
+
word.word_origins.build(origin_id: "")
|
2212
|
+
end
|
2213
|
+
|
2214
|
+
let(:word_origin) do
|
2215
|
+
word.word_origins.build(origin_id: "")
|
2216
|
+
end
|
2217
|
+
|
2218
|
+
it "returns true" do
|
2219
|
+
expect(word_origin).to be_valid
|
2220
|
+
end
|
2221
|
+
end
|
2222
|
+
end
|
2223
|
+
end
|
2224
|
+
end
|
2225
|
+
|
2226
|
+
context "when in an embeds_one" do
|
2227
|
+
|
2228
|
+
before do
|
2229
|
+
Pronunciation.validates_uniqueness_of :sound
|
2230
|
+
end
|
2231
|
+
|
2232
|
+
after do
|
2233
|
+
Pronunciation.reset_callbacks(:validate)
|
2234
|
+
end
|
2235
|
+
|
2236
|
+
let(:pronunciation) do
|
2237
|
+
word.build_pronunciation(sound: "Schwa")
|
2238
|
+
end
|
2239
|
+
|
2240
|
+
it "always returns true" do
|
2241
|
+
expect(pronunciation).to be_valid
|
2242
|
+
end
|
2243
|
+
end
|
2244
|
+
end
|
2245
|
+
|
2246
|
+
context "when describing validation on the instance level" do
|
2247
|
+
|
2248
|
+
let!(:dictionary) do
|
2249
|
+
Dictionary.create!(name: "en")
|
2250
|
+
end
|
2251
|
+
|
2252
|
+
let(:validators) do
|
2253
|
+
dictionary.validates_uniqueness_of :name
|
2254
|
+
end
|
2255
|
+
|
2256
|
+
it "adds the validation only to the instance" do
|
2257
|
+
expect(validators).to eq([ described_class ])
|
2258
|
+
end
|
2259
|
+
end
|
2260
|
+
|
2261
|
+
context "when validation works with inheritance" do
|
2262
|
+
|
2263
|
+
before do
|
2264
|
+
Actor.validates_uniqueness_of :name
|
2265
|
+
Actor.create!(name: "Johnny Depp")
|
2266
|
+
end
|
2267
|
+
|
2268
|
+
after do
|
2269
|
+
Actor.reset_callbacks(:validate)
|
2270
|
+
end
|
2271
|
+
|
2272
|
+
let!(:subclass_document_with_duplicated_name) do
|
2273
|
+
Actress.new(name: "Johnny Depp")
|
2274
|
+
end
|
2275
|
+
|
2276
|
+
it "should be invalid" do
|
2277
|
+
subclass_document_with_duplicated_name.tap do |d|
|
2278
|
+
expect(d).to be_invalid
|
2279
|
+
expect(d.errors[:name]).to eq([ "is already taken" ])
|
2280
|
+
end
|
2281
|
+
end
|
2282
|
+
end
|
2283
|
+
|
2284
|
+
context "when persisting with safe options" do
|
2285
|
+
|
2286
|
+
before do
|
2287
|
+
Person.validates_uniqueness_of(:username)
|
2288
|
+
Person.create_indexes
|
2289
|
+
end
|
2290
|
+
|
2291
|
+
let!(:person) do
|
2292
|
+
Person.create(ssn: "132-11-1111", username: "aaasdaffff")
|
2293
|
+
end
|
2294
|
+
|
2295
|
+
after do
|
2296
|
+
Person.reset_callbacks(:validate)
|
2297
|
+
end
|
2298
|
+
|
2299
|
+
it "transfers the options to the cloned session" do
|
2300
|
+
expect {
|
2301
|
+
Person.with(safe: true).create!(ssn: "132-11-1111", username: "asdfsdfA")
|
2302
|
+
}.to raise_error
|
2303
|
+
end
|
2304
|
+
end
|
2305
|
+
end
|