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,3556 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Relations::Referenced::ManyToMany do
|
4
|
+
|
5
|
+
before(:all) do
|
6
|
+
Mongoid.raise_not_found_error = true
|
7
|
+
Person.autosaved_relations.delete_one(:preferences)
|
8
|
+
Person.autosave(Person.relations["preferences"].merge!(autosave: true))
|
9
|
+
Person.synced(Person.relations["preferences"])
|
10
|
+
end
|
11
|
+
|
12
|
+
after(:all) do
|
13
|
+
Person.reset_callbacks(:save)
|
14
|
+
Person.reset_callbacks(:destroy)
|
15
|
+
end
|
16
|
+
|
17
|
+
[ :<<, :push ].each do |method|
|
18
|
+
|
19
|
+
describe "##{method}" do
|
20
|
+
|
21
|
+
context "when the inverse_of is nil" do
|
22
|
+
|
23
|
+
let!(:article) do
|
24
|
+
Article.create
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when the child document is new" do
|
28
|
+
|
29
|
+
let(:preference) do
|
30
|
+
Preference.new
|
31
|
+
end
|
32
|
+
|
33
|
+
before do
|
34
|
+
article.preferences.send(method, preference)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "persists the child document" do
|
38
|
+
expect(preference).to be_persisted
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "when the child document is not new" do
|
43
|
+
|
44
|
+
let(:preference) do
|
45
|
+
Preference.create
|
46
|
+
end
|
47
|
+
|
48
|
+
it "does not persist the child document" do
|
49
|
+
preference.should_receive(:save).never
|
50
|
+
article.preferences.send(method, preference)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "when the parent is a new record" do
|
56
|
+
|
57
|
+
let(:person) do
|
58
|
+
Person.new
|
59
|
+
end
|
60
|
+
|
61
|
+
let!(:preference) do
|
62
|
+
Preference.new
|
63
|
+
end
|
64
|
+
|
65
|
+
let(:result) do
|
66
|
+
person.preferences.send(method, preference)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "returns an array of loaded documents" do
|
70
|
+
expect(result).to eq([ preference ])
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
context "when the parent is not a new record" do
|
75
|
+
|
76
|
+
let(:person) do
|
77
|
+
Person.create
|
78
|
+
end
|
79
|
+
|
80
|
+
let!(:preference) do
|
81
|
+
Preference.new
|
82
|
+
end
|
83
|
+
|
84
|
+
let(:result) do
|
85
|
+
person.preferences.send(method, preference)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "returns an array of loaded documents" do
|
89
|
+
expect(result).to eq([ preference ])
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the relations are not polymorphic" do
|
94
|
+
|
95
|
+
context "when the inverse relation is not defined" do
|
96
|
+
|
97
|
+
let(:person) do
|
98
|
+
Person.new
|
99
|
+
end
|
100
|
+
|
101
|
+
let(:house) do
|
102
|
+
House.new
|
103
|
+
end
|
104
|
+
|
105
|
+
before do
|
106
|
+
person.houses << house
|
107
|
+
end
|
108
|
+
|
109
|
+
it "appends the document to the relation" do
|
110
|
+
expect(person.houses).to eq([ house ])
|
111
|
+
end
|
112
|
+
|
113
|
+
it "sets the foreign key on the relation" do
|
114
|
+
expect(person.house_ids).to eq([ house.id ])
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "when appending in a parent create block" do
|
119
|
+
|
120
|
+
let!(:preference) do
|
121
|
+
Preference.create(name: "testing")
|
122
|
+
end
|
123
|
+
|
124
|
+
let!(:person) do
|
125
|
+
Person.create do |doc|
|
126
|
+
doc.preferences << preference
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
it "adds the documents to the relation" do
|
131
|
+
expect(person.preferences).to eq([ preference ])
|
132
|
+
end
|
133
|
+
|
134
|
+
it "sets the foreign key on the relation" do
|
135
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
136
|
+
end
|
137
|
+
|
138
|
+
it "sets the foreign key on the inverse relation" do
|
139
|
+
expect(preference.person_ids).to eq([ person.id ])
|
140
|
+
end
|
141
|
+
|
142
|
+
it "saves the target" do
|
143
|
+
expect(preference).to be_persisted
|
144
|
+
end
|
145
|
+
|
146
|
+
it "adds the correct number of documents" do
|
147
|
+
expect(person.preferences.size).to eq(1)
|
148
|
+
end
|
149
|
+
|
150
|
+
it "persists the link" do
|
151
|
+
expect(person.reload.preferences).to eq([ preference ])
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
context "when the parent is a new record" do
|
156
|
+
|
157
|
+
let(:person) do
|
158
|
+
Person.new
|
159
|
+
end
|
160
|
+
|
161
|
+
context "when the child is new" do
|
162
|
+
|
163
|
+
let(:preference) do
|
164
|
+
Preference.new
|
165
|
+
end
|
166
|
+
|
167
|
+
before do
|
168
|
+
person.preferences.send(method, preference)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "adds the documents to the relation" do
|
172
|
+
expect(person.preferences).to eq([ preference ])
|
173
|
+
end
|
174
|
+
|
175
|
+
it "sets the foreign key on the relation" do
|
176
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
177
|
+
end
|
178
|
+
|
179
|
+
it "sets the foreign key on the inverse relation" do
|
180
|
+
expect(preference.person_ids).to eq([ person.id ])
|
181
|
+
end
|
182
|
+
|
183
|
+
it "does not save the target" do
|
184
|
+
expect(preference).to be_new_record
|
185
|
+
end
|
186
|
+
|
187
|
+
it "adds the correct number of documents" do
|
188
|
+
expect(person.preferences.size).to eq(1)
|
189
|
+
end
|
190
|
+
|
191
|
+
context "when appending a second time" do
|
192
|
+
|
193
|
+
before do
|
194
|
+
person.preferences.send(method, preference)
|
195
|
+
end
|
196
|
+
|
197
|
+
it "does not allow the document to be added again" do
|
198
|
+
expect(person.preferences).to eq([ preference ])
|
199
|
+
end
|
200
|
+
|
201
|
+
it "does not allow duplicate ids" do
|
202
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
context "when the child is already persisted" do
|
208
|
+
|
209
|
+
let!(:persisted) do
|
210
|
+
Preference.create(name: "testy")
|
211
|
+
end
|
212
|
+
|
213
|
+
let(:preference) do
|
214
|
+
Preference.first
|
215
|
+
end
|
216
|
+
|
217
|
+
before do
|
218
|
+
person.preferences.send(method, preference)
|
219
|
+
person.save
|
220
|
+
end
|
221
|
+
|
222
|
+
it "adds the documents to the relation" do
|
223
|
+
expect(person.preferences).to eq([ preference ])
|
224
|
+
end
|
225
|
+
|
226
|
+
it "sets the foreign key on the relation" do
|
227
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
228
|
+
end
|
229
|
+
|
230
|
+
it "sets the foreign key on the inverse relation" do
|
231
|
+
expect(preference.person_ids).to eq([ person.id ])
|
232
|
+
end
|
233
|
+
|
234
|
+
it "saves the target" do
|
235
|
+
expect(preference).to be_persisted
|
236
|
+
end
|
237
|
+
|
238
|
+
it "adds the correct number of documents" do
|
239
|
+
expect(person.preferences.size).to eq(1)
|
240
|
+
end
|
241
|
+
|
242
|
+
it "persists the link" do
|
243
|
+
expect(person.reload.preferences).to eq([ preference ])
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
context "when setting via the associated ids" do
|
248
|
+
|
249
|
+
let!(:persisted) do
|
250
|
+
Preference.create(name: "testy")
|
251
|
+
end
|
252
|
+
|
253
|
+
let(:preference) do
|
254
|
+
Preference.first
|
255
|
+
end
|
256
|
+
|
257
|
+
let(:person) do
|
258
|
+
Person.new(preference_ids: [ preference.id ])
|
259
|
+
end
|
260
|
+
|
261
|
+
before do
|
262
|
+
person.save
|
263
|
+
end
|
264
|
+
|
265
|
+
it "adds the documents to the relation" do
|
266
|
+
expect(person.preferences).to eq([ preference ])
|
267
|
+
end
|
268
|
+
|
269
|
+
it "sets the foreign key on the relation" do
|
270
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
271
|
+
end
|
272
|
+
|
273
|
+
it "sets the foreign key on the inverse relation" do
|
274
|
+
expect(preference.reload.person_ids).to eq([ person.id ])
|
275
|
+
end
|
276
|
+
|
277
|
+
it "adds the correct number of documents" do
|
278
|
+
expect(person.preferences.size).to eq(1)
|
279
|
+
end
|
280
|
+
|
281
|
+
it "persists the link" do
|
282
|
+
expect(person.reload.preferences).to eq([ preference ])
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
pending "when the identity map is enabled [ Github-3015 ]" do
|
287
|
+
|
288
|
+
let(:dungeon) do
|
289
|
+
Dungeon.new
|
290
|
+
end
|
291
|
+
|
292
|
+
let(:dragon) do
|
293
|
+
Dragon.new
|
294
|
+
end
|
295
|
+
|
296
|
+
before do
|
297
|
+
Mongoid.identity_map_enabled = true
|
298
|
+
dungeon.save!
|
299
|
+
dragon.dungeons.send(method, dungeon)
|
300
|
+
dragon.save!
|
301
|
+
end
|
302
|
+
|
303
|
+
after do
|
304
|
+
Mongoid.identity_map_enabled = false
|
305
|
+
end
|
306
|
+
|
307
|
+
it "sets the proper length of the child" do
|
308
|
+
expect(dragon.dungeons.length).to eq(1)
|
309
|
+
end
|
310
|
+
|
311
|
+
it "sets the proper number of foreign keys" do
|
312
|
+
expect(dungeon.dragon_ids.length).to eq(1)
|
313
|
+
end
|
314
|
+
|
315
|
+
it "sets the proper number of parent docs" do
|
316
|
+
expect(dungeon.dragons.length).to eq(1)
|
317
|
+
end
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
context "when the parent is not a new record" do
|
322
|
+
|
323
|
+
let(:person) do
|
324
|
+
Person.create
|
325
|
+
end
|
326
|
+
|
327
|
+
let(:preference) do
|
328
|
+
Preference.new
|
329
|
+
end
|
330
|
+
|
331
|
+
before do
|
332
|
+
person.preferences.send(method, preference)
|
333
|
+
end
|
334
|
+
|
335
|
+
it "adds the documents to the relation" do
|
336
|
+
expect(person.preferences).to eq([ preference ])
|
337
|
+
end
|
338
|
+
|
339
|
+
it "sets the foreign key on the relation" do
|
340
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
341
|
+
end
|
342
|
+
|
343
|
+
it "sets the foreign key on the inverse relation" do
|
344
|
+
expect(preference.person_ids).to eq([ person.id ])
|
345
|
+
end
|
346
|
+
|
347
|
+
it "sets the base on the inverse relation" do
|
348
|
+
expect(preference.people).to eq([ person ])
|
349
|
+
end
|
350
|
+
|
351
|
+
it "sets the same instance on the inverse relation" do
|
352
|
+
expect(preference.people.first).to eql(person)
|
353
|
+
end
|
354
|
+
|
355
|
+
it "saves the target" do
|
356
|
+
expect(preference).to_not be_new_record
|
357
|
+
end
|
358
|
+
|
359
|
+
it "adds the document to the target" do
|
360
|
+
expect(person.preferences.count).to eq(1)
|
361
|
+
end
|
362
|
+
|
363
|
+
context "when documents already exist on the relation" do
|
364
|
+
|
365
|
+
let(:preference_two) do
|
366
|
+
Preference.new
|
367
|
+
end
|
368
|
+
|
369
|
+
before do
|
370
|
+
person.preferences.send(method, preference_two)
|
371
|
+
end
|
372
|
+
|
373
|
+
it "adds the documents to the relation" do
|
374
|
+
expect(person.preferences).to eq([ preference, preference_two ])
|
375
|
+
end
|
376
|
+
|
377
|
+
it "sets the foreign key on the relation" do
|
378
|
+
expect(person.preference_ids).to eq([ preference.id, preference_two.id ])
|
379
|
+
end
|
380
|
+
|
381
|
+
it "sets the foreign key on the inverse relation" do
|
382
|
+
expect(preference_two.person_ids).to eq([ person.id ])
|
383
|
+
end
|
384
|
+
|
385
|
+
it "sets the base on the inverse relation" do
|
386
|
+
expect(preference_two.people).to eq([ person ])
|
387
|
+
end
|
388
|
+
|
389
|
+
it "sets the same instance on the inverse relation" do
|
390
|
+
expect(preference_two.people.first).to eql(person)
|
391
|
+
end
|
392
|
+
|
393
|
+
it "saves the target" do
|
394
|
+
expect(preference).to_not be_new_record
|
395
|
+
end
|
396
|
+
|
397
|
+
it "adds the document to the target" do
|
398
|
+
expect(person.preferences.count).to eq(2)
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
context "when both sides have been persisted" do
|
404
|
+
|
405
|
+
let(:person) do
|
406
|
+
Person.create
|
407
|
+
end
|
408
|
+
|
409
|
+
let(:event) do
|
410
|
+
Event.create
|
411
|
+
end
|
412
|
+
|
413
|
+
before do
|
414
|
+
person.administrated_events << event
|
415
|
+
end
|
416
|
+
|
417
|
+
it "sets the front side of the relation" do
|
418
|
+
expect(person.administrated_events).to eq([ event ])
|
419
|
+
end
|
420
|
+
|
421
|
+
it "sets the inverse side of the relation" do
|
422
|
+
expect(event.administrators(true)).to eq([ person ])
|
423
|
+
end
|
424
|
+
|
425
|
+
context "when reloading" do
|
426
|
+
|
427
|
+
it "sets the front side of the relation" do
|
428
|
+
expect(person.reload.administrated_events).to eq([ event ])
|
429
|
+
end
|
430
|
+
|
431
|
+
it "sets the inverse side of the relation" do
|
432
|
+
expect(event.reload.administrators).to eq([ person ])
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
context "when performing a new database query" do
|
437
|
+
|
438
|
+
let(:loaded_person) do
|
439
|
+
Person.find(person.id)
|
440
|
+
end
|
441
|
+
|
442
|
+
let(:loaded_event) do
|
443
|
+
Event.find(event.id)
|
444
|
+
end
|
445
|
+
|
446
|
+
it "sets the front side of the relation" do
|
447
|
+
expect(loaded_person.administrated_events).to eq([ event ])
|
448
|
+
end
|
449
|
+
|
450
|
+
it "sets the inverse side of the relation" do
|
451
|
+
expect(loaded_event.administrators).to eq([ person ])
|
452
|
+
end
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
context "when the relation also includes a has_many relation" do
|
457
|
+
|
458
|
+
let(:artwork) do
|
459
|
+
Artwork.create
|
460
|
+
end
|
461
|
+
|
462
|
+
let(:exhibition) do
|
463
|
+
Exhibition.create
|
464
|
+
end
|
465
|
+
|
466
|
+
let(:exhibitor) do
|
467
|
+
Exhibitor.create(exhibition: exhibition)
|
468
|
+
end
|
469
|
+
|
470
|
+
before do
|
471
|
+
artwork.exhibitors << exhibitor
|
472
|
+
end
|
473
|
+
|
474
|
+
it "creates a single artwork object" do
|
475
|
+
expect(Artwork.count).to eq(1)
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
context "when the relation is self referencing" do
|
480
|
+
|
481
|
+
let(:tag_one) do
|
482
|
+
Tag.create(text: "one")
|
483
|
+
end
|
484
|
+
|
485
|
+
let(:tag_two) do
|
486
|
+
Tag.create(text: "two")
|
487
|
+
end
|
488
|
+
|
489
|
+
before do
|
490
|
+
tag_one.related << tag_two
|
491
|
+
end
|
492
|
+
|
493
|
+
it "sets the front side of the relation" do
|
494
|
+
expect(tag_one.related).to eq([ tag_two ])
|
495
|
+
end
|
496
|
+
|
497
|
+
it "sets the inverse side of the relation" do
|
498
|
+
expect(tag_two.related(true)).to eq([ tag_one ])
|
499
|
+
end
|
500
|
+
|
501
|
+
context "when reloading" do
|
502
|
+
|
503
|
+
it "sets the front side of the relation" do
|
504
|
+
expect(tag_one.reload.related).to eq([ tag_two ])
|
505
|
+
end
|
506
|
+
|
507
|
+
it "sets the inverse side of the relation" do
|
508
|
+
expect(tag_two.reload.related).to eq([ tag_one ])
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
context "when performing a new database query" do
|
513
|
+
|
514
|
+
let(:loaded_tag_one) do
|
515
|
+
Tag.find(tag_one.id)
|
516
|
+
end
|
517
|
+
|
518
|
+
let(:loaded_tag_two) do
|
519
|
+
Tag.find(tag_two.id)
|
520
|
+
end
|
521
|
+
|
522
|
+
it "sets the front side of the relation" do
|
523
|
+
expect(loaded_tag_one.related).to eq([ tag_two ])
|
524
|
+
end
|
525
|
+
|
526
|
+
it "sets the inverse side of the relation" do
|
527
|
+
expect(loaded_tag_two.related).to eq([ tag_one ])
|
528
|
+
end
|
529
|
+
end
|
530
|
+
end
|
531
|
+
end
|
532
|
+
|
533
|
+
context "when association has callbacks" do
|
534
|
+
|
535
|
+
let(:post) do
|
536
|
+
Post.new
|
537
|
+
end
|
538
|
+
|
539
|
+
let(:tag) do
|
540
|
+
Tag.new
|
541
|
+
end
|
542
|
+
|
543
|
+
context "when the callback is a before_add" do
|
544
|
+
|
545
|
+
it "executes the callback" do
|
546
|
+
post.tags.send(method, tag)
|
547
|
+
expect(post.before_add_called).to be_true
|
548
|
+
end
|
549
|
+
|
550
|
+
context "when errors are raised" do
|
551
|
+
|
552
|
+
before do
|
553
|
+
post.should_receive(:before_add_tag).and_raise
|
554
|
+
end
|
555
|
+
|
556
|
+
it "does not add the document to the relation" do
|
557
|
+
expect {
|
558
|
+
post.tags.send(method, tag)
|
559
|
+
}.to raise_error
|
560
|
+
expect(post.tags).to be_empty
|
561
|
+
end
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
context "when the callback is an after_add" do
|
566
|
+
|
567
|
+
it "executes the callback" do
|
568
|
+
post.tags.send(method, tag)
|
569
|
+
expect(post.after_add_called).to be_true
|
570
|
+
end
|
571
|
+
|
572
|
+
context "when errors are raised" do
|
573
|
+
|
574
|
+
before do
|
575
|
+
post.should_receive(:after_add_tag).and_raise
|
576
|
+
end
|
577
|
+
|
578
|
+
it "adds the document to the relation" do
|
579
|
+
expect {
|
580
|
+
post.tags.send(method, tag)
|
581
|
+
}.to raise_error
|
582
|
+
expect(post.tags).to eq([ tag ])
|
583
|
+
end
|
584
|
+
end
|
585
|
+
end
|
586
|
+
end
|
587
|
+
end
|
588
|
+
end
|
589
|
+
|
590
|
+
describe "#=" do
|
591
|
+
|
592
|
+
context "when trying to add duplicate entries" do
|
593
|
+
|
594
|
+
let(:person) do
|
595
|
+
Person.new
|
596
|
+
end
|
597
|
+
|
598
|
+
let(:preference) do
|
599
|
+
Preference.create(name: "one")
|
600
|
+
end
|
601
|
+
|
602
|
+
before do
|
603
|
+
person.preferences = [ preference, preference ]
|
604
|
+
end
|
605
|
+
|
606
|
+
context "when the document is new" do
|
607
|
+
|
608
|
+
it "does not add the duplicates" do
|
609
|
+
expect(person.preferences).to eq([ preference ])
|
610
|
+
end
|
611
|
+
|
612
|
+
it "does not create duplicate keys" do
|
613
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
614
|
+
end
|
615
|
+
end
|
616
|
+
|
617
|
+
context "when the document is persisted" do
|
618
|
+
|
619
|
+
before do
|
620
|
+
person.save
|
621
|
+
end
|
622
|
+
|
623
|
+
it "does not add the duplicates" do
|
624
|
+
expect(person.preferences).to eq([ preference ])
|
625
|
+
end
|
626
|
+
|
627
|
+
it "does not create duplicate keys" do
|
628
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
629
|
+
end
|
630
|
+
|
631
|
+
it "does not add duplicates on the inverse" do
|
632
|
+
expect(preference.people).to eq([ person ])
|
633
|
+
end
|
634
|
+
|
635
|
+
it "does not add duplicate inverse keys" do
|
636
|
+
expect(preference.person_ids).to eq([ person.id ])
|
637
|
+
end
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
context "when the relation is not polymorphic" do
|
642
|
+
|
643
|
+
context "when the parent and relation are new records" do
|
644
|
+
|
645
|
+
let(:person) do
|
646
|
+
Person.new
|
647
|
+
end
|
648
|
+
|
649
|
+
let(:preference) do
|
650
|
+
Preference.new
|
651
|
+
end
|
652
|
+
|
653
|
+
before do
|
654
|
+
person.preferences = [ preference ]
|
655
|
+
end
|
656
|
+
|
657
|
+
it "sets the relation" do
|
658
|
+
expect(person.preferences).to eq([ preference ])
|
659
|
+
end
|
660
|
+
|
661
|
+
it "sets the foreign key on the relation" do
|
662
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
663
|
+
end
|
664
|
+
|
665
|
+
it "sets the foreign key on the inverse relation" do
|
666
|
+
expect(preference.person_ids).to eq([ person.id ])
|
667
|
+
end
|
668
|
+
|
669
|
+
it "does not save the target" do
|
670
|
+
expect(preference).to be_new_record
|
671
|
+
end
|
672
|
+
end
|
673
|
+
|
674
|
+
context "when the parent is new but the relation exists" do
|
675
|
+
|
676
|
+
let(:person) do
|
677
|
+
Person.new
|
678
|
+
end
|
679
|
+
|
680
|
+
let!(:preference) do
|
681
|
+
Preference.create
|
682
|
+
end
|
683
|
+
|
684
|
+
before do
|
685
|
+
person.preferences = [ preference ]
|
686
|
+
end
|
687
|
+
|
688
|
+
it "sets the relation" do
|
689
|
+
expect(person.preferences).to eq([ preference ])
|
690
|
+
end
|
691
|
+
|
692
|
+
it "sets the foreign key on the relation" do
|
693
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
694
|
+
end
|
695
|
+
|
696
|
+
it "sets the foreign key on the inverse relation" do
|
697
|
+
expect(preference.person_ids).to eq([ person.id ])
|
698
|
+
end
|
699
|
+
|
700
|
+
context "and the parent is persisted" do
|
701
|
+
|
702
|
+
before do
|
703
|
+
person.save!
|
704
|
+
preference.reload
|
705
|
+
end
|
706
|
+
|
707
|
+
it "maintains the relation" do
|
708
|
+
expect(person.preferences).to eq([ preference ])
|
709
|
+
end
|
710
|
+
|
711
|
+
it "maintains the foreign key on the relation" do
|
712
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
713
|
+
end
|
714
|
+
|
715
|
+
it "maintains the foreign key on the inverse relation" do
|
716
|
+
expect(preference.person_ids).to eq([ person.id ])
|
717
|
+
end
|
718
|
+
|
719
|
+
it "maintains the base on the inverse relation" do
|
720
|
+
expect(preference.people.first).to eq(person)
|
721
|
+
end
|
722
|
+
end
|
723
|
+
end
|
724
|
+
|
725
|
+
context "when the parent is not a new record" do
|
726
|
+
|
727
|
+
let(:person) do
|
728
|
+
Person.create
|
729
|
+
end
|
730
|
+
|
731
|
+
let(:preference) do
|
732
|
+
Preference.new
|
733
|
+
end
|
734
|
+
|
735
|
+
before do
|
736
|
+
person.preferences = [ preference ]
|
737
|
+
end
|
738
|
+
|
739
|
+
it "sets the relation" do
|
740
|
+
expect(person.preferences).to eq([ preference ])
|
741
|
+
end
|
742
|
+
|
743
|
+
it "sets the foreign key on the relation" do
|
744
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
745
|
+
end
|
746
|
+
|
747
|
+
it "sets the foreign key on the inverse relation" do
|
748
|
+
expect(preference.person_ids).to eq([ person.id ])
|
749
|
+
end
|
750
|
+
|
751
|
+
it "sets the base on the inverse relation" do
|
752
|
+
expect(preference.people.first).to eq(person)
|
753
|
+
end
|
754
|
+
|
755
|
+
it "saves the target" do
|
756
|
+
expect(preference).to be_persisted
|
757
|
+
end
|
758
|
+
|
759
|
+
it "persists the relation" do
|
760
|
+
person.reload.preferences == [ preference ]
|
761
|
+
end
|
762
|
+
|
763
|
+
context "when overwriting an existing relation" do
|
764
|
+
|
765
|
+
let(:another_preference) do
|
766
|
+
Preference.new
|
767
|
+
end
|
768
|
+
|
769
|
+
before do
|
770
|
+
person.preferences = [ another_preference ]
|
771
|
+
end
|
772
|
+
|
773
|
+
it "sets the relation" do
|
774
|
+
expect(person.preferences).to eq([ another_preference ])
|
775
|
+
end
|
776
|
+
|
777
|
+
it "saves the target" do
|
778
|
+
expect(another_preference).to be_persisted
|
779
|
+
end
|
780
|
+
|
781
|
+
it "does not leave foreign keys of the previous relation" do
|
782
|
+
expect(person.preference_ids).to eq([ another_preference.id ])
|
783
|
+
end
|
784
|
+
|
785
|
+
it "clears its own key on the foreign relation" do
|
786
|
+
expect(preference.person_ids).to be_empty
|
787
|
+
end
|
788
|
+
|
789
|
+
context "and then overwriting it again with the same value" do
|
790
|
+
|
791
|
+
before do
|
792
|
+
person.preferences = [ another_preference ]
|
793
|
+
end
|
794
|
+
|
795
|
+
it "persists the relation between another_preference and person" do
|
796
|
+
expect(another_preference.reload.people).to eq([ person ])
|
797
|
+
end
|
798
|
+
|
799
|
+
end
|
800
|
+
|
801
|
+
context "and person reloaded instead of saved" do
|
802
|
+
|
803
|
+
before do
|
804
|
+
person.reload
|
805
|
+
another_preference.reload
|
806
|
+
end
|
807
|
+
|
808
|
+
it "persists the relation between person and another_preference" do
|
809
|
+
expect(person.preferences).to eq([ another_preference ])
|
810
|
+
end
|
811
|
+
|
812
|
+
it "persists the relation between another_prefrence and person" do
|
813
|
+
expect(another_preference.people).to eq([ person ])
|
814
|
+
end
|
815
|
+
|
816
|
+
it "no longer has any relation between preference and person" do
|
817
|
+
expect(preference.people).to be_empty
|
818
|
+
end
|
819
|
+
end
|
820
|
+
|
821
|
+
context "and person is saved" do
|
822
|
+
|
823
|
+
before do
|
824
|
+
person.save
|
825
|
+
person.reload
|
826
|
+
another_preference.reload
|
827
|
+
end
|
828
|
+
|
829
|
+
it "persists the relation between person and another_preference" do
|
830
|
+
expect(person.preferences).to eq([ another_preference ])
|
831
|
+
end
|
832
|
+
|
833
|
+
it "persists the relation between another_prefrence and person" do
|
834
|
+
expect(another_preference.people).to eq([ person ])
|
835
|
+
end
|
836
|
+
|
837
|
+
it "no longer has any relation between preference and person" do
|
838
|
+
expect(preference.people).to be_empty
|
839
|
+
end
|
840
|
+
end
|
841
|
+
end
|
842
|
+
end
|
843
|
+
end
|
844
|
+
end
|
845
|
+
|
846
|
+
[ nil, [] ].each do |value|
|
847
|
+
|
848
|
+
describe "#= #{value}" do
|
849
|
+
|
850
|
+
context "when the relation is not polymorphic" do
|
851
|
+
|
852
|
+
context "when the inverse relation is not defined" do
|
853
|
+
|
854
|
+
let(:person) do
|
855
|
+
Person.new
|
856
|
+
end
|
857
|
+
|
858
|
+
let(:house) do
|
859
|
+
House.new
|
860
|
+
end
|
861
|
+
|
862
|
+
before do
|
863
|
+
person.houses << house
|
864
|
+
person.houses = value
|
865
|
+
end
|
866
|
+
|
867
|
+
it "clears the relation" do
|
868
|
+
expect(person.houses).to be_empty
|
869
|
+
end
|
870
|
+
|
871
|
+
it "clears the foreign keys" do
|
872
|
+
expect(person.house_ids).to be_empty
|
873
|
+
end
|
874
|
+
end
|
875
|
+
|
876
|
+
context "when the parent is a new record" do
|
877
|
+
|
878
|
+
let(:person) do
|
879
|
+
Person.new
|
880
|
+
end
|
881
|
+
|
882
|
+
let(:preference) do
|
883
|
+
Preference.new
|
884
|
+
end
|
885
|
+
|
886
|
+
before do
|
887
|
+
person.preferences = [ preference ]
|
888
|
+
person.preferences = value
|
889
|
+
end
|
890
|
+
|
891
|
+
it "sets the relation to an empty array" do
|
892
|
+
expect(person.preferences).to be_empty
|
893
|
+
end
|
894
|
+
|
895
|
+
it "removed the inverse relation" do
|
896
|
+
expect(preference.people).to be_empty
|
897
|
+
end
|
898
|
+
|
899
|
+
it "removes the foreign key values" do
|
900
|
+
expect(person.preference_ids).to be_empty
|
901
|
+
end
|
902
|
+
|
903
|
+
it "removes the inverse foreign key values" do
|
904
|
+
expect(preference.person_ids).to be_empty
|
905
|
+
end
|
906
|
+
end
|
907
|
+
|
908
|
+
context "when the parent is not a new record" do
|
909
|
+
|
910
|
+
context "when the relation has been loaded" do
|
911
|
+
|
912
|
+
let(:person) do
|
913
|
+
Person.create
|
914
|
+
end
|
915
|
+
|
916
|
+
let(:preference) do
|
917
|
+
Preference.new
|
918
|
+
end
|
919
|
+
|
920
|
+
before do
|
921
|
+
person.preferences = [ preference ]
|
922
|
+
person.preferences = value
|
923
|
+
end
|
924
|
+
|
925
|
+
it "sets the relation to an empty array" do
|
926
|
+
expect(person.preferences).to be_empty
|
927
|
+
end
|
928
|
+
|
929
|
+
it "removed the inverse relation" do
|
930
|
+
expect(preference.people).to be_empty
|
931
|
+
end
|
932
|
+
|
933
|
+
it "removes the foreign key values" do
|
934
|
+
expect(person.preference_ids).to be_empty
|
935
|
+
end
|
936
|
+
|
937
|
+
it "removes the inverse foreign key values" do
|
938
|
+
expect(preference.person_ids).to be_empty
|
939
|
+
end
|
940
|
+
|
941
|
+
it "does not delete the target from the database" do
|
942
|
+
expect(preference).to_not be_destroyed
|
943
|
+
end
|
944
|
+
end
|
945
|
+
|
946
|
+
context "when the relation has not been loaded" do
|
947
|
+
|
948
|
+
let(:preference) do
|
949
|
+
Preference.new
|
950
|
+
end
|
951
|
+
|
952
|
+
let(:person) do
|
953
|
+
Person.create.tap do |p|
|
954
|
+
p.preferences = [ preference ]
|
955
|
+
end
|
956
|
+
end
|
957
|
+
|
958
|
+
let!(:from_db) do
|
959
|
+
Person.find(person.id)
|
960
|
+
end
|
961
|
+
|
962
|
+
before do
|
963
|
+
from_db.preferences = value
|
964
|
+
end
|
965
|
+
|
966
|
+
it "sets the relation to an empty array" do
|
967
|
+
expect(from_db.preferences).to be_empty
|
968
|
+
end
|
969
|
+
|
970
|
+
it "removes the foreign key values" do
|
971
|
+
expect(from_db.preference_ids).to be_empty
|
972
|
+
end
|
973
|
+
end
|
974
|
+
end
|
975
|
+
end
|
976
|
+
end
|
977
|
+
end
|
978
|
+
|
979
|
+
[ :build, :new ].each do |method|
|
980
|
+
|
981
|
+
describe "##{method}" do
|
982
|
+
|
983
|
+
context "when the relation is not polymorphic" do
|
984
|
+
|
985
|
+
context "when the parent is a new record" do
|
986
|
+
|
987
|
+
let(:person) do
|
988
|
+
Person.new
|
989
|
+
end
|
990
|
+
|
991
|
+
let!(:preference) do
|
992
|
+
person.preferences.send(method, name: "settings")
|
993
|
+
end
|
994
|
+
|
995
|
+
it "adds the document to the relation" do
|
996
|
+
expect(person.preferences).to eq([ preference ])
|
997
|
+
end
|
998
|
+
|
999
|
+
it "sets the foreign key on the relation" do
|
1000
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1001
|
+
end
|
1002
|
+
|
1003
|
+
it "sets the inverse foreign key on the relation" do
|
1004
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1005
|
+
end
|
1006
|
+
|
1007
|
+
it "sets the attributes" do
|
1008
|
+
expect(preference.name).to eq("settings")
|
1009
|
+
end
|
1010
|
+
|
1011
|
+
it "does not save the target" do
|
1012
|
+
expect(preference).to be_new_record
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
it "adds the correct number of documents" do
|
1016
|
+
expect(person.preferences.size).to eq(1)
|
1017
|
+
end
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
context "when the parent is not a new record" do
|
1021
|
+
|
1022
|
+
let(:person) do
|
1023
|
+
Person.create
|
1024
|
+
end
|
1025
|
+
|
1026
|
+
let!(:preference) do
|
1027
|
+
person.preferences.send(method, name: "settings")
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
it "adds the document to the relation" do
|
1031
|
+
expect(person.preferences).to eq([ preference ])
|
1032
|
+
end
|
1033
|
+
|
1034
|
+
it "sets the foreign key on the relation" do
|
1035
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
it "sets the inverse foreign key on the relation" do
|
1039
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1040
|
+
end
|
1041
|
+
|
1042
|
+
it "sets the base on the inverse relation" do
|
1043
|
+
expect(preference.people).to eq([ person ])
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
it "sets the attributes" do
|
1047
|
+
expect(preference.name).to eq("settings")
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
it "does not save the target" do
|
1051
|
+
expect(preference).to be_new_record
|
1052
|
+
end
|
1053
|
+
|
1054
|
+
it "adds the correct number of documents" do
|
1055
|
+
expect(person.preferences.size).to eq(1)
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
context "when saving the target" do
|
1059
|
+
|
1060
|
+
before do
|
1061
|
+
preference.save
|
1062
|
+
end
|
1063
|
+
|
1064
|
+
it "persists the parent keys" do
|
1065
|
+
expect(person.reload.preference_ids).to eq([ preference.id ])
|
1066
|
+
end
|
1067
|
+
end
|
1068
|
+
end
|
1069
|
+
end
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
describe ".builder" do
|
1074
|
+
|
1075
|
+
let(:builder_klass) do
|
1076
|
+
Mongoid::Relations::Builders::Referenced::ManyToMany
|
1077
|
+
end
|
1078
|
+
|
1079
|
+
let(:document) do
|
1080
|
+
double
|
1081
|
+
end
|
1082
|
+
|
1083
|
+
let(:metadata) do
|
1084
|
+
double(extension?: false)
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
it "returns the embedded in builder" do
|
1088
|
+
expect(
|
1089
|
+
described_class.builder(nil, metadata, document)
|
1090
|
+
).to be_a_kind_of(builder_klass)
|
1091
|
+
end
|
1092
|
+
end
|
1093
|
+
|
1094
|
+
describe "#clear" do
|
1095
|
+
|
1096
|
+
context "when the relation is not polymorphic" do
|
1097
|
+
|
1098
|
+
context "when the parent has been persisted" do
|
1099
|
+
|
1100
|
+
let!(:person) do
|
1101
|
+
Person.create
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
context "when the children are persisted" do
|
1105
|
+
|
1106
|
+
let!(:preference) do
|
1107
|
+
person.preferences.create(name: "settings")
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
let!(:relation) do
|
1111
|
+
person.preferences.clear
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
it "clears out the relation" do
|
1115
|
+
expect(person.preferences).to be_empty
|
1116
|
+
end
|
1117
|
+
|
1118
|
+
it "removes the parent from the inverse relation" do
|
1119
|
+
expect(preference.people).to_not include(person)
|
1120
|
+
end
|
1121
|
+
|
1122
|
+
it "removes the foreign keys" do
|
1123
|
+
expect(person.preference_ids).to be_empty
|
1124
|
+
end
|
1125
|
+
|
1126
|
+
it "removes the parent key from the inverse" do
|
1127
|
+
expect(preference.person_ids).to_not include(person.id)
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
it "does not delete the documents" do
|
1131
|
+
expect(preference).to_not be_destroyed
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
it "persists the nullification" do
|
1135
|
+
expect(person.reload.preferences).to be_empty
|
1136
|
+
end
|
1137
|
+
|
1138
|
+
it "returns the relation" do
|
1139
|
+
expect(relation).to be_empty
|
1140
|
+
end
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
context "when the children are not persisted" do
|
1144
|
+
|
1145
|
+
let!(:preference) do
|
1146
|
+
person.preferences.build(name: "setting")
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
let!(:relation) do
|
1150
|
+
person.preferences.clear
|
1151
|
+
end
|
1152
|
+
|
1153
|
+
it "clears out the relation" do
|
1154
|
+
expect(person.preferences).to be_empty
|
1155
|
+
end
|
1156
|
+
end
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
context "when the parent is not persisted" do
|
1160
|
+
|
1161
|
+
let(:person) do
|
1162
|
+
Person.new
|
1163
|
+
end
|
1164
|
+
|
1165
|
+
let!(:preference) do
|
1166
|
+
person.preferences.build(name: "setting")
|
1167
|
+
end
|
1168
|
+
|
1169
|
+
let!(:relation) do
|
1170
|
+
person.preferences.clear
|
1171
|
+
end
|
1172
|
+
|
1173
|
+
it "clears out the relation" do
|
1174
|
+
expect(person.preferences).to be_empty
|
1175
|
+
end
|
1176
|
+
end
|
1177
|
+
end
|
1178
|
+
|
1179
|
+
context "when the association has callbacks" do
|
1180
|
+
|
1181
|
+
let(:post) do
|
1182
|
+
Post.new
|
1183
|
+
end
|
1184
|
+
|
1185
|
+
let(:tag) do
|
1186
|
+
Tag.new
|
1187
|
+
end
|
1188
|
+
|
1189
|
+
before do
|
1190
|
+
post.tags << tag
|
1191
|
+
end
|
1192
|
+
|
1193
|
+
context "when the callback is a before_remove" do
|
1194
|
+
|
1195
|
+
context "when no errors are raised" do
|
1196
|
+
|
1197
|
+
before do
|
1198
|
+
post.tags.clear
|
1199
|
+
end
|
1200
|
+
|
1201
|
+
it "executes the callback" do
|
1202
|
+
expect(post.before_remove_called).to be_true
|
1203
|
+
end
|
1204
|
+
|
1205
|
+
it "removes the document from the relation" do
|
1206
|
+
expect(post.tags).to be_empty
|
1207
|
+
end
|
1208
|
+
end
|
1209
|
+
|
1210
|
+
context "when errors are raised" do
|
1211
|
+
|
1212
|
+
before do
|
1213
|
+
post.should_receive(:before_remove_tag).and_raise
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
it "does not remove the document from the relation" do
|
1217
|
+
expect {
|
1218
|
+
post.tags.clear
|
1219
|
+
}.to raise_error
|
1220
|
+
expect(post.tags).to eq([ tag ])
|
1221
|
+
end
|
1222
|
+
end
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
context "when the callback is an after_remove" do
|
1226
|
+
|
1227
|
+
context "when no errors are raised" do
|
1228
|
+
|
1229
|
+
before do
|
1230
|
+
post.tags.clear
|
1231
|
+
end
|
1232
|
+
|
1233
|
+
it "executes the callback" do
|
1234
|
+
expect(post.after_remove_called).to be_true
|
1235
|
+
end
|
1236
|
+
|
1237
|
+
it "removes the document from the relation" do
|
1238
|
+
expect(post.tags).to be_empty
|
1239
|
+
end
|
1240
|
+
end
|
1241
|
+
|
1242
|
+
context "when errors are raised" do
|
1243
|
+
|
1244
|
+
before do
|
1245
|
+
post.should_receive(:after_remove_tag).and_raise
|
1246
|
+
end
|
1247
|
+
|
1248
|
+
it "removes the document from the relation" do
|
1249
|
+
expect {
|
1250
|
+
post.tags.clear
|
1251
|
+
}.to raise_error
|
1252
|
+
expect(post.tags).to be_empty
|
1253
|
+
end
|
1254
|
+
end
|
1255
|
+
end
|
1256
|
+
end
|
1257
|
+
end
|
1258
|
+
|
1259
|
+
describe "#concat" do
|
1260
|
+
|
1261
|
+
context "when the parent is a new record" do
|
1262
|
+
|
1263
|
+
let(:person) do
|
1264
|
+
Person.new
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
let!(:preference) do
|
1268
|
+
Preference.new
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
let(:result) do
|
1272
|
+
person.preferences.concat([ preference ])
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
it "returns an array of loaded documents" do
|
1276
|
+
expect(result).to eq([ preference ])
|
1277
|
+
end
|
1278
|
+
end
|
1279
|
+
|
1280
|
+
context "when the parent is not a new record" do
|
1281
|
+
|
1282
|
+
let(:person) do
|
1283
|
+
Person.create
|
1284
|
+
end
|
1285
|
+
|
1286
|
+
let!(:preference) do
|
1287
|
+
Preference.new
|
1288
|
+
end
|
1289
|
+
|
1290
|
+
let(:result) do
|
1291
|
+
person.preferences.concat([ preference ])
|
1292
|
+
end
|
1293
|
+
|
1294
|
+
it "returns an array of loaded documents" do
|
1295
|
+
expect(result).to eq([ preference ])
|
1296
|
+
end
|
1297
|
+
end
|
1298
|
+
|
1299
|
+
context "when the relations are not polymorphic" do
|
1300
|
+
|
1301
|
+
context "when the inverse relation is not defined" do
|
1302
|
+
|
1303
|
+
let(:person) do
|
1304
|
+
Person.new
|
1305
|
+
end
|
1306
|
+
|
1307
|
+
let(:house) do
|
1308
|
+
House.new
|
1309
|
+
end
|
1310
|
+
|
1311
|
+
before do
|
1312
|
+
person.houses.concat([ house ])
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
it "appends the document to the relation" do
|
1316
|
+
expect(person.houses).to eq([ house ])
|
1317
|
+
end
|
1318
|
+
|
1319
|
+
it "sets the foreign key on the relation" do
|
1320
|
+
expect(person.house_ids).to eq([ house.id ])
|
1321
|
+
end
|
1322
|
+
end
|
1323
|
+
|
1324
|
+
context "when appending in a parent create block" do
|
1325
|
+
|
1326
|
+
let!(:preference) do
|
1327
|
+
Preference.create(name: "testing")
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
let!(:person) do
|
1331
|
+
Person.create do |doc|
|
1332
|
+
doc.preferences.concat([ preference ])
|
1333
|
+
end
|
1334
|
+
end
|
1335
|
+
|
1336
|
+
it "adds the documents to the relation" do
|
1337
|
+
expect(person.preferences).to eq([ preference ])
|
1338
|
+
end
|
1339
|
+
|
1340
|
+
it "sets the foreign key on the relation" do
|
1341
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
it "sets the foreign key on the inverse relation" do
|
1345
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1346
|
+
end
|
1347
|
+
|
1348
|
+
it "saves the target" do
|
1349
|
+
expect(preference).to be_persisted
|
1350
|
+
end
|
1351
|
+
|
1352
|
+
it "adds the correct number of documents" do
|
1353
|
+
expect(person.preferences.size).to eq(1)
|
1354
|
+
end
|
1355
|
+
|
1356
|
+
it "persists the link" do
|
1357
|
+
expect(person.reload.preferences).to eq([ preference ])
|
1358
|
+
end
|
1359
|
+
end
|
1360
|
+
|
1361
|
+
context "when the parent is a new record" do
|
1362
|
+
|
1363
|
+
let(:person) do
|
1364
|
+
Person.new
|
1365
|
+
end
|
1366
|
+
|
1367
|
+
context "when the child is new" do
|
1368
|
+
|
1369
|
+
let(:preference) do
|
1370
|
+
Preference.new
|
1371
|
+
end
|
1372
|
+
|
1373
|
+
before do
|
1374
|
+
person.preferences.concat([ preference ])
|
1375
|
+
end
|
1376
|
+
|
1377
|
+
it "adds the documents to the relation" do
|
1378
|
+
expect(person.preferences).to eq([ preference ])
|
1379
|
+
end
|
1380
|
+
|
1381
|
+
it "sets the foreign key on the relation" do
|
1382
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1383
|
+
end
|
1384
|
+
|
1385
|
+
it "sets the foreign key on the inverse relation" do
|
1386
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1387
|
+
end
|
1388
|
+
|
1389
|
+
it "does not save the target" do
|
1390
|
+
expect(preference).to be_new_record
|
1391
|
+
end
|
1392
|
+
|
1393
|
+
it "adds the correct number of documents" do
|
1394
|
+
expect(person.preferences.size).to eq(1)
|
1395
|
+
end
|
1396
|
+
|
1397
|
+
context "when appending a second time" do
|
1398
|
+
|
1399
|
+
before do
|
1400
|
+
person.preferences.concat([ preference ])
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
it "does not allow the document to be added again" do
|
1404
|
+
expect(person.preferences).to eq([ preference ])
|
1405
|
+
end
|
1406
|
+
|
1407
|
+
it "does not allow duplicate ids" do
|
1408
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1409
|
+
end
|
1410
|
+
end
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
context "when the child is already persisted" do
|
1414
|
+
|
1415
|
+
let!(:persisted) do
|
1416
|
+
Preference.create(name: "testy")
|
1417
|
+
end
|
1418
|
+
|
1419
|
+
let(:preference) do
|
1420
|
+
Preference.first
|
1421
|
+
end
|
1422
|
+
|
1423
|
+
before do
|
1424
|
+
person.preferences.concat([ preference ])
|
1425
|
+
person.save
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
it "adds the documents to the relation" do
|
1429
|
+
expect(person.preferences).to eq([ preference ])
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
it "sets the foreign key on the relation" do
|
1433
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1434
|
+
end
|
1435
|
+
|
1436
|
+
it "sets the foreign key on the inverse relation" do
|
1437
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1438
|
+
end
|
1439
|
+
|
1440
|
+
it "saves the target" do
|
1441
|
+
expect(preference).to be_persisted
|
1442
|
+
end
|
1443
|
+
|
1444
|
+
it "adds the correct number of documents" do
|
1445
|
+
expect(person.preferences.size).to eq(1)
|
1446
|
+
end
|
1447
|
+
|
1448
|
+
it "persists the link" do
|
1449
|
+
expect(person.reload.preferences).to eq([ preference ])
|
1450
|
+
end
|
1451
|
+
end
|
1452
|
+
|
1453
|
+
context "when setting via the associated ids" do
|
1454
|
+
|
1455
|
+
let!(:persisted) do
|
1456
|
+
Preference.create(name: "testy")
|
1457
|
+
end
|
1458
|
+
|
1459
|
+
let(:preference) do
|
1460
|
+
Preference.first
|
1461
|
+
end
|
1462
|
+
|
1463
|
+
let(:person) do
|
1464
|
+
Person.new(preference_ids: [ preference.id ])
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
before do
|
1468
|
+
person.save
|
1469
|
+
end
|
1470
|
+
|
1471
|
+
it "adds the documents to the relation" do
|
1472
|
+
expect(person.preferences).to eq([ preference ])
|
1473
|
+
end
|
1474
|
+
|
1475
|
+
it "sets the foreign key on the relation" do
|
1476
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1477
|
+
end
|
1478
|
+
|
1479
|
+
it "sets the foreign key on the inverse relation" do
|
1480
|
+
expect(preference.reload.person_ids).to eq([ person.id ])
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
it "adds the correct number of documents" do
|
1484
|
+
expect(person.preferences.size).to eq(1)
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
it "persists the link" do
|
1488
|
+
expect(person.reload.preferences).to eq([ preference ])
|
1489
|
+
end
|
1490
|
+
end
|
1491
|
+
end
|
1492
|
+
|
1493
|
+
context "when the parent is not a new record" do
|
1494
|
+
|
1495
|
+
let(:person) do
|
1496
|
+
Person.create
|
1497
|
+
end
|
1498
|
+
|
1499
|
+
let(:preference) do
|
1500
|
+
Preference.new
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
before do
|
1504
|
+
person.preferences.concat([ preference ])
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
it "adds the documents to the relation" do
|
1508
|
+
expect(person.preferences).to eq([ preference ])
|
1509
|
+
end
|
1510
|
+
|
1511
|
+
it "sets the foreign key on the relation" do
|
1512
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1513
|
+
end
|
1514
|
+
|
1515
|
+
it "sets the foreign key on the inverse relation" do
|
1516
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1517
|
+
end
|
1518
|
+
|
1519
|
+
it "sets the base on the inverse relation" do
|
1520
|
+
expect(preference.people).to eq([ person ])
|
1521
|
+
end
|
1522
|
+
|
1523
|
+
it "sets the same instance on the inverse relation" do
|
1524
|
+
expect(preference.people.first).to eql(person)
|
1525
|
+
end
|
1526
|
+
|
1527
|
+
it "saves the target" do
|
1528
|
+
expect(preference).to_not be_new_record
|
1529
|
+
end
|
1530
|
+
|
1531
|
+
it "adds the document to the target" do
|
1532
|
+
expect(person.preferences.count).to eq(1)
|
1533
|
+
end
|
1534
|
+
|
1535
|
+
context "when documents already exist on the relation" do
|
1536
|
+
|
1537
|
+
let(:preference_two) do
|
1538
|
+
Preference.new
|
1539
|
+
end
|
1540
|
+
|
1541
|
+
before do
|
1542
|
+
person.preferences.concat([ preference_two ])
|
1543
|
+
end
|
1544
|
+
|
1545
|
+
it "adds the documents to the relation" do
|
1546
|
+
expect(person.preferences).to eq([ preference, preference_two ])
|
1547
|
+
end
|
1548
|
+
|
1549
|
+
it "sets the foreign key on the relation" do
|
1550
|
+
expect(person.preference_ids).to eq([ preference.id, preference_two.id ])
|
1551
|
+
end
|
1552
|
+
|
1553
|
+
it "sets the foreign key on the inverse relation" do
|
1554
|
+
expect(preference_two.person_ids).to eq([ person.id ])
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
it "sets the base on the inverse relation" do
|
1558
|
+
expect(preference_two.people).to eq([ person ])
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
it "sets the same instance on the inverse relation" do
|
1562
|
+
expect(preference_two.people.first).to eql(person)
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
it "saves the target" do
|
1566
|
+
expect(preference).to_not be_new_record
|
1567
|
+
end
|
1568
|
+
|
1569
|
+
it "adds the document to the target" do
|
1570
|
+
expect(person.preferences.count).to eq(2)
|
1571
|
+
end
|
1572
|
+
end
|
1573
|
+
end
|
1574
|
+
|
1575
|
+
context "when both sides have been persisted" do
|
1576
|
+
|
1577
|
+
let(:person) do
|
1578
|
+
Person.create
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
let(:event) do
|
1582
|
+
Event.create
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
before do
|
1586
|
+
person.administrated_events.concat([ event ])
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
it "sets the front side of the relation" do
|
1590
|
+
expect(person.administrated_events).to eq([ event ])
|
1591
|
+
end
|
1592
|
+
|
1593
|
+
it "sets the inverse side of the relation" do
|
1594
|
+
expect(event.administrators(true)).to eq([ person ])
|
1595
|
+
end
|
1596
|
+
|
1597
|
+
context "when reloading" do
|
1598
|
+
|
1599
|
+
it "sets the front side of the relation" do
|
1600
|
+
expect(person.reload.administrated_events).to eq([ event ])
|
1601
|
+
end
|
1602
|
+
|
1603
|
+
it "sets the inverse side of the relation" do
|
1604
|
+
expect(event.reload.administrators).to eq([ person ])
|
1605
|
+
end
|
1606
|
+
end
|
1607
|
+
|
1608
|
+
context "when performing a new database query" do
|
1609
|
+
|
1610
|
+
let(:loaded_person) do
|
1611
|
+
Person.find(person.id)
|
1612
|
+
end
|
1613
|
+
|
1614
|
+
let(:loaded_event) do
|
1615
|
+
Event.find(event.id)
|
1616
|
+
end
|
1617
|
+
|
1618
|
+
it "sets the front side of the relation" do
|
1619
|
+
expect(loaded_person.administrated_events).to eq([ event ])
|
1620
|
+
end
|
1621
|
+
|
1622
|
+
it "sets the inverse side of the relation" do
|
1623
|
+
expect(loaded_event.administrators).to eq([ person ])
|
1624
|
+
end
|
1625
|
+
end
|
1626
|
+
end
|
1627
|
+
|
1628
|
+
context "when the relation also includes a has_many relation" do
|
1629
|
+
|
1630
|
+
let(:artwork) do
|
1631
|
+
Artwork.create
|
1632
|
+
end
|
1633
|
+
|
1634
|
+
let(:exhibition) do
|
1635
|
+
Exhibition.create
|
1636
|
+
end
|
1637
|
+
|
1638
|
+
let(:exhibitor) do
|
1639
|
+
Exhibitor.create(exhibition: exhibition)
|
1640
|
+
end
|
1641
|
+
|
1642
|
+
before do
|
1643
|
+
artwork.exhibitors.concat([ exhibitor ])
|
1644
|
+
end
|
1645
|
+
|
1646
|
+
it "creates a single artwork object" do
|
1647
|
+
expect(Artwork.count).to eq(1)
|
1648
|
+
end
|
1649
|
+
end
|
1650
|
+
|
1651
|
+
context "when the relation is self referencing" do
|
1652
|
+
|
1653
|
+
let(:tag_one) do
|
1654
|
+
Tag.create(text: "one")
|
1655
|
+
end
|
1656
|
+
|
1657
|
+
let(:tag_two) do
|
1658
|
+
Tag.create(text: "two")
|
1659
|
+
end
|
1660
|
+
|
1661
|
+
before do
|
1662
|
+
tag_one.related.concat([ tag_two ])
|
1663
|
+
end
|
1664
|
+
|
1665
|
+
it "sets the front side of the relation" do
|
1666
|
+
expect(tag_one.related).to eq([ tag_two ])
|
1667
|
+
end
|
1668
|
+
|
1669
|
+
it "sets the inverse side of the relation" do
|
1670
|
+
expect(tag_two.related(true)).to eq([ tag_one ])
|
1671
|
+
end
|
1672
|
+
|
1673
|
+
context "when reloading" do
|
1674
|
+
|
1675
|
+
it "sets the front side of the relation" do
|
1676
|
+
expect(tag_one.reload.related).to eq([ tag_two ])
|
1677
|
+
end
|
1678
|
+
|
1679
|
+
it "sets the inverse side of the relation" do
|
1680
|
+
expect(tag_two.reload.related).to eq([ tag_one ])
|
1681
|
+
end
|
1682
|
+
end
|
1683
|
+
|
1684
|
+
context "when performing a new database query" do
|
1685
|
+
|
1686
|
+
let(:loaded_tag_one) do
|
1687
|
+
Tag.find(tag_one.id)
|
1688
|
+
end
|
1689
|
+
|
1690
|
+
let(:loaded_tag_two) do
|
1691
|
+
Tag.find(tag_two.id)
|
1692
|
+
end
|
1693
|
+
|
1694
|
+
it "sets the front side of the relation" do
|
1695
|
+
expect(loaded_tag_one.related).to eq([ tag_two ])
|
1696
|
+
end
|
1697
|
+
|
1698
|
+
it "sets the inverse side of the relation" do
|
1699
|
+
expect(loaded_tag_two.related).to eq([ tag_one ])
|
1700
|
+
end
|
1701
|
+
end
|
1702
|
+
end
|
1703
|
+
end
|
1704
|
+
end
|
1705
|
+
|
1706
|
+
describe "#count" do
|
1707
|
+
|
1708
|
+
let(:person) do
|
1709
|
+
Person.create
|
1710
|
+
end
|
1711
|
+
|
1712
|
+
context "when nothing exists on the relation" do
|
1713
|
+
|
1714
|
+
context "when the document is destroyed" do
|
1715
|
+
|
1716
|
+
before do
|
1717
|
+
Meat.create!
|
1718
|
+
end
|
1719
|
+
|
1720
|
+
let!(:sandwich) do
|
1721
|
+
Sandwich.create!
|
1722
|
+
end
|
1723
|
+
|
1724
|
+
it "returns zero" do
|
1725
|
+
sandwich.destroy
|
1726
|
+
expect(sandwich.meats.count).to eq(0)
|
1727
|
+
end
|
1728
|
+
end
|
1729
|
+
end
|
1730
|
+
|
1731
|
+
context "when documents have been persisted" do
|
1732
|
+
|
1733
|
+
let!(:preference) do
|
1734
|
+
person.preferences.create(name: "setting")
|
1735
|
+
end
|
1736
|
+
|
1737
|
+
it "returns the number of persisted documents" do
|
1738
|
+
expect(person.preferences.count).to eq(1)
|
1739
|
+
end
|
1740
|
+
end
|
1741
|
+
|
1742
|
+
context "when appending to a loaded relation" do
|
1743
|
+
|
1744
|
+
let!(:preference) do
|
1745
|
+
person.preferences.create(name: "setting")
|
1746
|
+
end
|
1747
|
+
|
1748
|
+
before do
|
1749
|
+
person.preferences.count
|
1750
|
+
person.preferences << Preference.create(name: "two")
|
1751
|
+
end
|
1752
|
+
|
1753
|
+
it "returns the number of persisted documents" do
|
1754
|
+
expect(person.preferences.count).to eq(2)
|
1755
|
+
end
|
1756
|
+
end
|
1757
|
+
|
1758
|
+
context "when documents have not been persisted" do
|
1759
|
+
|
1760
|
+
let!(:preference) do
|
1761
|
+
person.preferences.build(name: "settings")
|
1762
|
+
end
|
1763
|
+
|
1764
|
+
it "returns 0" do
|
1765
|
+
expect(person.preferences.count).to eq(0)
|
1766
|
+
end
|
1767
|
+
end
|
1768
|
+
|
1769
|
+
context "when new documents exist in the database" do
|
1770
|
+
|
1771
|
+
context "when the documents are part of the relation" do
|
1772
|
+
|
1773
|
+
before do
|
1774
|
+
Preference.create(person_ids: [ person.id ])
|
1775
|
+
end
|
1776
|
+
|
1777
|
+
it "returns the count from the db" do
|
1778
|
+
expect(person.reload.preferences.count).to eq(1)
|
1779
|
+
end
|
1780
|
+
end
|
1781
|
+
|
1782
|
+
context "when the documents are not part of the relation" do
|
1783
|
+
|
1784
|
+
before do
|
1785
|
+
Preference.create
|
1786
|
+
end
|
1787
|
+
|
1788
|
+
it "returns the count from the db" do
|
1789
|
+
expect(person.preferences.count).to eq(0)
|
1790
|
+
end
|
1791
|
+
end
|
1792
|
+
end
|
1793
|
+
|
1794
|
+
context "when the inverse relation is not defined" do
|
1795
|
+
|
1796
|
+
context "when documents have been persisted" do
|
1797
|
+
|
1798
|
+
let!(:house) do
|
1799
|
+
person.houses.create(name: "Wayne Manor")
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
it "returns the number of persisted documents" do
|
1803
|
+
expect(person.houses.count).to eq(1)
|
1804
|
+
end
|
1805
|
+
end
|
1806
|
+
|
1807
|
+
context "when documents have not been persisted" do
|
1808
|
+
|
1809
|
+
let!(:house) do
|
1810
|
+
person.houses.build(name: "Ryugyong Hotel")
|
1811
|
+
end
|
1812
|
+
|
1813
|
+
it "returns 0" do
|
1814
|
+
expect(person.preferences.count).to eq(0)
|
1815
|
+
end
|
1816
|
+
end
|
1817
|
+
end
|
1818
|
+
end
|
1819
|
+
|
1820
|
+
[ :create, :create! ].each do |method|
|
1821
|
+
|
1822
|
+
describe "##{method}" do
|
1823
|
+
|
1824
|
+
context "when the relation is not polymorphic" do
|
1825
|
+
|
1826
|
+
context "when using string keys" do
|
1827
|
+
|
1828
|
+
let(:agent) do
|
1829
|
+
Agent.create(number: "007")
|
1830
|
+
end
|
1831
|
+
|
1832
|
+
before do
|
1833
|
+
agent.accounts.create(name: "testing again")
|
1834
|
+
end
|
1835
|
+
|
1836
|
+
it "does not convert the string key to an object id" do
|
1837
|
+
expect(agent.account_ids).to eq([ "testing-again" ])
|
1838
|
+
end
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
context "when the parent is a new record" do
|
1842
|
+
|
1843
|
+
let(:person) do
|
1844
|
+
Person.new
|
1845
|
+
end
|
1846
|
+
|
1847
|
+
it "raises an unsaved document error" do
|
1848
|
+
expect {
|
1849
|
+
person.preferences.send(method, name: "Testing")
|
1850
|
+
}.to raise_error(Mongoid::Errors::UnsavedDocument)
|
1851
|
+
end
|
1852
|
+
end
|
1853
|
+
|
1854
|
+
context "when the parent is not a new record" do
|
1855
|
+
|
1856
|
+
let(:person) do
|
1857
|
+
Person.send(method)
|
1858
|
+
end
|
1859
|
+
|
1860
|
+
let!(:preference) do
|
1861
|
+
person.preferences.send(method, name: "Testing")
|
1862
|
+
end
|
1863
|
+
|
1864
|
+
it "sets the foreign key on the relation" do
|
1865
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
it "sets the foreign key on the inverse relation" do
|
1869
|
+
expect(preference.person_ids).to eq([ person.id ])
|
1870
|
+
end
|
1871
|
+
|
1872
|
+
it "adds the document" do
|
1873
|
+
expect(person.preferences).to eq([ preference ])
|
1874
|
+
end
|
1875
|
+
|
1876
|
+
it "sets the base on the inverse relation" do
|
1877
|
+
expect(preference.people).to eq([ person ])
|
1878
|
+
end
|
1879
|
+
|
1880
|
+
it "sets the attributes" do
|
1881
|
+
expect(preference.name).to eq("Testing")
|
1882
|
+
end
|
1883
|
+
|
1884
|
+
it "saves the target" do
|
1885
|
+
expect(preference).to be_persisted
|
1886
|
+
end
|
1887
|
+
|
1888
|
+
it "adds the document to the target" do
|
1889
|
+
expect(person.preferences.count).to eq(1)
|
1890
|
+
end
|
1891
|
+
|
1892
|
+
it "does not duplicate documents" do
|
1893
|
+
expect(person.reload.preferences.count).to eq(1)
|
1894
|
+
end
|
1895
|
+
|
1896
|
+
it "does not duplicate ids" do
|
1897
|
+
expect(person.reload.preference_ids.count).to eq(1)
|
1898
|
+
end
|
1899
|
+
end
|
1900
|
+
end
|
1901
|
+
end
|
1902
|
+
end
|
1903
|
+
|
1904
|
+
describe "#create!" do
|
1905
|
+
|
1906
|
+
context "when validation fails" do
|
1907
|
+
|
1908
|
+
let(:person) do
|
1909
|
+
Person.create
|
1910
|
+
end
|
1911
|
+
|
1912
|
+
context "when the relation is not polymorphic" do
|
1913
|
+
|
1914
|
+
it "raises an error" do
|
1915
|
+
expect {
|
1916
|
+
person.preferences.create!(name: "a")
|
1917
|
+
}.to raise_error(Mongoid::Errors::Validations)
|
1918
|
+
end
|
1919
|
+
end
|
1920
|
+
end
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
describe "#delete" do
|
1924
|
+
|
1925
|
+
let(:person) do
|
1926
|
+
Person.create
|
1927
|
+
end
|
1928
|
+
|
1929
|
+
let(:preference_one) do
|
1930
|
+
Preference.create(name: "Testing")
|
1931
|
+
end
|
1932
|
+
|
1933
|
+
let(:preference_two) do
|
1934
|
+
Preference.create(name: "Test")
|
1935
|
+
end
|
1936
|
+
|
1937
|
+
before do
|
1938
|
+
person.preferences << [ preference_one, preference_two ]
|
1939
|
+
end
|
1940
|
+
|
1941
|
+
context "when the document exists" do
|
1942
|
+
|
1943
|
+
let!(:deleted) do
|
1944
|
+
person.preferences.delete(preference_one)
|
1945
|
+
end
|
1946
|
+
|
1947
|
+
it "removes the document from the relation" do
|
1948
|
+
expect(person.preferences).to eq([ preference_two ])
|
1949
|
+
end
|
1950
|
+
|
1951
|
+
it "returns the document" do
|
1952
|
+
expect(deleted).to eq(preference_one)
|
1953
|
+
end
|
1954
|
+
|
1955
|
+
it "removes the document key from the foreign key" do
|
1956
|
+
expect(person.preference_ids).to eq([ preference_two.id ])
|
1957
|
+
end
|
1958
|
+
|
1959
|
+
it "removes the inverse reference" do
|
1960
|
+
expect(deleted.reload.people).to be_empty
|
1961
|
+
end
|
1962
|
+
|
1963
|
+
it "removes the base id from the inverse keys" do
|
1964
|
+
expect(deleted.reload.person_ids).to be_empty
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
context "and person and preferences are reloaded" do
|
1968
|
+
|
1969
|
+
before do
|
1970
|
+
person.reload
|
1971
|
+
preference_one.reload
|
1972
|
+
preference_two.reload
|
1973
|
+
end
|
1974
|
+
|
1975
|
+
it "nullifies the deleted preference" do
|
1976
|
+
expect(person.preferences).to eq([ preference_two ])
|
1977
|
+
end
|
1978
|
+
|
1979
|
+
it "retains the ids for one preference" do
|
1980
|
+
expect(person.preference_ids).to eq([ preference_two.id ])
|
1981
|
+
end
|
1982
|
+
end
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
context "when the document does not exist" do
|
1986
|
+
|
1987
|
+
let!(:deleted) do
|
1988
|
+
person.preferences.delete(Preference.new)
|
1989
|
+
end
|
1990
|
+
|
1991
|
+
it "returns nil" do
|
1992
|
+
expect(deleted).to be_nil
|
1993
|
+
end
|
1994
|
+
|
1995
|
+
it "does not modify the relation" do
|
1996
|
+
expect(person.preferences).to eq([ preference_one, preference_two ])
|
1997
|
+
end
|
1998
|
+
|
1999
|
+
it "does not modify the keys" do
|
2000
|
+
expect(person.preference_ids).to eq([ preference_one.id, preference_two.id ])
|
2001
|
+
end
|
2002
|
+
end
|
2003
|
+
|
2004
|
+
context "when :dependent => :nullify is set" do
|
2005
|
+
|
2006
|
+
context "when :inverse_of is set" do
|
2007
|
+
|
2008
|
+
let(:event) do
|
2009
|
+
Event.create
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
before do
|
2013
|
+
person.administrated_events << [ event ]
|
2014
|
+
end
|
2015
|
+
|
2016
|
+
it "deletes the document" do
|
2017
|
+
expect(event.delete).to be_true
|
2018
|
+
end
|
2019
|
+
end
|
2020
|
+
end
|
2021
|
+
|
2022
|
+
context "when the relationships are self referencing" do
|
2023
|
+
|
2024
|
+
let(:tag_one) do
|
2025
|
+
Tag.create(text: "one")
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
let(:tag_two) do
|
2029
|
+
Tag.create(text: "two")
|
2030
|
+
end
|
2031
|
+
|
2032
|
+
before do
|
2033
|
+
tag_one.related << tag_two
|
2034
|
+
end
|
2035
|
+
|
2036
|
+
context "when deleting without reloading" do
|
2037
|
+
|
2038
|
+
let!(:deleted) do
|
2039
|
+
tag_one.related.delete(tag_two)
|
2040
|
+
end
|
2041
|
+
|
2042
|
+
it "deletes the document from the relation" do
|
2043
|
+
expect(tag_one.related).to be_empty
|
2044
|
+
end
|
2045
|
+
|
2046
|
+
it "deletes the foreign key from the relation" do
|
2047
|
+
expect(tag_one.related_ids).to be_empty
|
2048
|
+
end
|
2049
|
+
|
2050
|
+
it "removes the reference from the inverse" do
|
2051
|
+
expect(deleted.related).to be_empty
|
2052
|
+
end
|
2053
|
+
|
2054
|
+
it "removes the foreign keys from the inverse" do
|
2055
|
+
expect(deleted.related_ids).to be_empty
|
2056
|
+
end
|
2057
|
+
end
|
2058
|
+
|
2059
|
+
context "when deleting with reloading" do
|
2060
|
+
|
2061
|
+
context "when deleting from the front side" do
|
2062
|
+
|
2063
|
+
let(:reloaded) do
|
2064
|
+
tag_one.reload
|
2065
|
+
end
|
2066
|
+
|
2067
|
+
let!(:deleted) do
|
2068
|
+
reloaded.related.delete(tag_two)
|
2069
|
+
end
|
2070
|
+
|
2071
|
+
it "deletes the document from the relation" do
|
2072
|
+
expect(reloaded.related).to be_empty
|
2073
|
+
end
|
2074
|
+
|
2075
|
+
it "deletes the foreign key from the relation" do
|
2076
|
+
expect(reloaded.related_ids).to be_empty
|
2077
|
+
end
|
2078
|
+
|
2079
|
+
it "removes the reference from the inverse" do
|
2080
|
+
expect(deleted.related).to be_empty
|
2081
|
+
end
|
2082
|
+
|
2083
|
+
it "removes the foreign keys from the inverse" do
|
2084
|
+
expect(deleted.related_ids).to be_empty
|
2085
|
+
end
|
2086
|
+
end
|
2087
|
+
|
2088
|
+
context "when deleting from the inverse side" do
|
2089
|
+
|
2090
|
+
let(:reloaded) do
|
2091
|
+
tag_two.reload
|
2092
|
+
end
|
2093
|
+
|
2094
|
+
let!(:deleted) do
|
2095
|
+
reloaded.related.delete(tag_one)
|
2096
|
+
end
|
2097
|
+
|
2098
|
+
it "deletes the document from the relation" do
|
2099
|
+
expect(reloaded.related).to be_empty
|
2100
|
+
end
|
2101
|
+
|
2102
|
+
it "deletes the foreign key from the relation" do
|
2103
|
+
expect(reloaded.related_ids).to be_empty
|
2104
|
+
end
|
2105
|
+
|
2106
|
+
it "removes the foreign keys from the inverse" do
|
2107
|
+
expect(deleted.related_ids).to be_empty
|
2108
|
+
end
|
2109
|
+
end
|
2110
|
+
end
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
context "when the association has callbacks" do
|
2114
|
+
|
2115
|
+
let(:post) do
|
2116
|
+
Post.new
|
2117
|
+
end
|
2118
|
+
|
2119
|
+
let(:tag) do
|
2120
|
+
Tag.new
|
2121
|
+
end
|
2122
|
+
|
2123
|
+
before do
|
2124
|
+
post.tags << tag
|
2125
|
+
end
|
2126
|
+
|
2127
|
+
context "when the callback is a before_remove" do
|
2128
|
+
|
2129
|
+
context "when there are no errors" do
|
2130
|
+
|
2131
|
+
before do
|
2132
|
+
post.tags.delete tag
|
2133
|
+
end
|
2134
|
+
|
2135
|
+
it "executes the callback" do
|
2136
|
+
expect(post.before_remove_called).to be_true
|
2137
|
+
end
|
2138
|
+
|
2139
|
+
it "removes the document from the relation" do
|
2140
|
+
expect(post.tags).to be_empty
|
2141
|
+
end
|
2142
|
+
end
|
2143
|
+
|
2144
|
+
context "when errors are raised" do
|
2145
|
+
|
2146
|
+
before do
|
2147
|
+
post.should_receive(:before_remove_tag).and_raise
|
2148
|
+
end
|
2149
|
+
|
2150
|
+
it "does not remove the document from the relation" do
|
2151
|
+
expect {
|
2152
|
+
post.tags.delete tag
|
2153
|
+
}.to raise_error
|
2154
|
+
expect(post.tags).to eq([ tag ])
|
2155
|
+
end
|
2156
|
+
end
|
2157
|
+
end
|
2158
|
+
|
2159
|
+
context "when the callback is an after_remove" do
|
2160
|
+
|
2161
|
+
context "when no errors are raised" do
|
2162
|
+
|
2163
|
+
before do
|
2164
|
+
post.tags.delete(tag)
|
2165
|
+
end
|
2166
|
+
|
2167
|
+
it "executes the callback" do
|
2168
|
+
expect(post.after_remove_called).to be_true
|
2169
|
+
end
|
2170
|
+
|
2171
|
+
it "removes the document from the relation" do
|
2172
|
+
expect(post.tags).to be_empty
|
2173
|
+
end
|
2174
|
+
end
|
2175
|
+
|
2176
|
+
context "when errors are raised" do
|
2177
|
+
|
2178
|
+
before do
|
2179
|
+
post.should_receive(:after_remove_tag).and_raise
|
2180
|
+
end
|
2181
|
+
|
2182
|
+
it "removes the document from the relation" do
|
2183
|
+
expect {
|
2184
|
+
post.tags.delete(tag)
|
2185
|
+
}.to raise_error
|
2186
|
+
expect(post.tags).to be_empty
|
2187
|
+
end
|
2188
|
+
end
|
2189
|
+
end
|
2190
|
+
end
|
2191
|
+
end
|
2192
|
+
|
2193
|
+
[ :delete_all, :destroy_all ].each do |method|
|
2194
|
+
|
2195
|
+
describe "##{method}" do
|
2196
|
+
|
2197
|
+
context "when the relation is not polymorphic" do
|
2198
|
+
|
2199
|
+
context "when conditions are provided" do
|
2200
|
+
|
2201
|
+
let(:person) do
|
2202
|
+
Person.create
|
2203
|
+
end
|
2204
|
+
|
2205
|
+
let!(:preference_one) do
|
2206
|
+
person.preferences.create(name: "Testing")
|
2207
|
+
end
|
2208
|
+
|
2209
|
+
let!(:preference_two) do
|
2210
|
+
person.preferences.create(name: "Test")
|
2211
|
+
end
|
2212
|
+
|
2213
|
+
let!(:deleted) do
|
2214
|
+
person.preferences.send(
|
2215
|
+
method,
|
2216
|
+
{ name: "Testing" }
|
2217
|
+
)
|
2218
|
+
end
|
2219
|
+
|
2220
|
+
it "removes the correct preferences" do
|
2221
|
+
expect(person.preferences.count).to eq(1)
|
2222
|
+
end
|
2223
|
+
|
2224
|
+
it "deletes the documents from the database" do
|
2225
|
+
expect(Preference.where(name: "Testing").count).to eq(0)
|
2226
|
+
end
|
2227
|
+
|
2228
|
+
it "returns the number of documents deleted" do
|
2229
|
+
expect(deleted).to eq(1)
|
2230
|
+
end
|
2231
|
+
|
2232
|
+
it "removes the ids from the foreign key" do
|
2233
|
+
expect(person.preference_ids).to eq([ preference_two.id ])
|
2234
|
+
end
|
2235
|
+
end
|
2236
|
+
|
2237
|
+
context "when conditions are not provided" do
|
2238
|
+
|
2239
|
+
let(:person) do
|
2240
|
+
Person.create.tap do |person|
|
2241
|
+
person.preferences.create(name: "Testing")
|
2242
|
+
person.preferences.create(name: "Test")
|
2243
|
+
end
|
2244
|
+
end
|
2245
|
+
|
2246
|
+
let!(:deleted) do
|
2247
|
+
person.preferences.send(method)
|
2248
|
+
end
|
2249
|
+
|
2250
|
+
it "removes the correct preferences" do
|
2251
|
+
expect(person.preferences.count).to eq(0)
|
2252
|
+
end
|
2253
|
+
|
2254
|
+
it "deletes the documents from the database" do
|
2255
|
+
expect(Preference.count).to eq(0)
|
2256
|
+
end
|
2257
|
+
|
2258
|
+
it "returns the number of documents deleted" do
|
2259
|
+
expect(deleted).to eq(2)
|
2260
|
+
end
|
2261
|
+
end
|
2262
|
+
end
|
2263
|
+
end
|
2264
|
+
end
|
2265
|
+
|
2266
|
+
describe ".eager_load" do
|
2267
|
+
|
2268
|
+
before do
|
2269
|
+
Mongoid.identity_map_enabled = true
|
2270
|
+
end
|
2271
|
+
|
2272
|
+
after do
|
2273
|
+
Mongoid.identity_map_enabled = false
|
2274
|
+
end
|
2275
|
+
|
2276
|
+
context "when the relation is not polymorphic" do
|
2277
|
+
|
2278
|
+
let!(:person) do
|
2279
|
+
Person.create
|
2280
|
+
end
|
2281
|
+
|
2282
|
+
let!(:preference) do
|
2283
|
+
person.preferences.create(name: "testing")
|
2284
|
+
end
|
2285
|
+
|
2286
|
+
let(:metadata) do
|
2287
|
+
Person.relations["preferences"]
|
2288
|
+
end
|
2289
|
+
|
2290
|
+
let(:ids) do
|
2291
|
+
[ preference.id ]
|
2292
|
+
end
|
2293
|
+
|
2294
|
+
let!(:eager) do
|
2295
|
+
described_class.eager_load(metadata, ids)
|
2296
|
+
end
|
2297
|
+
|
2298
|
+
let(:map) do
|
2299
|
+
Mongoid::IdentityMap.get(Preference, ids)
|
2300
|
+
end
|
2301
|
+
|
2302
|
+
it "puts the documents in the identity map" do
|
2303
|
+
expect(map).to eq([ preference ])
|
2304
|
+
end
|
2305
|
+
end
|
2306
|
+
end
|
2307
|
+
|
2308
|
+
describe ".embedded?" do
|
2309
|
+
|
2310
|
+
it "returns false" do
|
2311
|
+
expect(described_class).to_not be_embedded
|
2312
|
+
end
|
2313
|
+
end
|
2314
|
+
|
2315
|
+
describe "#exists?" do
|
2316
|
+
|
2317
|
+
let!(:person) do
|
2318
|
+
Person.create
|
2319
|
+
end
|
2320
|
+
|
2321
|
+
context "when documents exist in the database" do
|
2322
|
+
|
2323
|
+
before do
|
2324
|
+
person.preferences.create
|
2325
|
+
end
|
2326
|
+
|
2327
|
+
it "returns true" do
|
2328
|
+
expect(person.preferences.exists?).to be_true
|
2329
|
+
end
|
2330
|
+
end
|
2331
|
+
|
2332
|
+
context "when no documents exist in the database" do
|
2333
|
+
|
2334
|
+
before do
|
2335
|
+
person.preferences.build
|
2336
|
+
end
|
2337
|
+
|
2338
|
+
it "returns false" do
|
2339
|
+
expect(person.preferences.exists?).to be_false
|
2340
|
+
end
|
2341
|
+
end
|
2342
|
+
end
|
2343
|
+
|
2344
|
+
describe "#find" do
|
2345
|
+
|
2346
|
+
context "when the relation is not polymorphic" do
|
2347
|
+
|
2348
|
+
let(:person) do
|
2349
|
+
Person.create
|
2350
|
+
end
|
2351
|
+
|
2352
|
+
let!(:preference_one) do
|
2353
|
+
person.preferences.create(name: "Test")
|
2354
|
+
end
|
2355
|
+
|
2356
|
+
let!(:preference_two) do
|
2357
|
+
person.preferences.create(name: "OMG I has relations")
|
2358
|
+
end
|
2359
|
+
|
2360
|
+
let!(:unrelated_pref) do
|
2361
|
+
Preference.create(name: "orphan annie")
|
2362
|
+
end
|
2363
|
+
|
2364
|
+
let!(:unrelated_pref_two) do
|
2365
|
+
Preference.create(name: "orphan two")
|
2366
|
+
end
|
2367
|
+
|
2368
|
+
context "when providing an id" do
|
2369
|
+
|
2370
|
+
context "when the id matches" do
|
2371
|
+
|
2372
|
+
let(:preference) do
|
2373
|
+
person.preferences.find(preference_one.id)
|
2374
|
+
end
|
2375
|
+
|
2376
|
+
it "returns the matching document" do
|
2377
|
+
expect(preference).to eq(preference_one)
|
2378
|
+
end
|
2379
|
+
end
|
2380
|
+
|
2381
|
+
context "when the id matches an unreferenced document" do
|
2382
|
+
|
2383
|
+
let(:preference) do
|
2384
|
+
person.preferences.find(unrelated_pref.id)
|
2385
|
+
end
|
2386
|
+
|
2387
|
+
it "raises an error" do
|
2388
|
+
expect {
|
2389
|
+
preference
|
2390
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
2391
|
+
end
|
2392
|
+
end
|
2393
|
+
|
2394
|
+
context "when the id does not match" do
|
2395
|
+
|
2396
|
+
context "when config set to raise error" do
|
2397
|
+
|
2398
|
+
before do
|
2399
|
+
Mongoid.raise_not_found_error = true
|
2400
|
+
end
|
2401
|
+
|
2402
|
+
it "raises an error" do
|
2403
|
+
expect {
|
2404
|
+
person.preferences.find(Moped::BSON::ObjectId.new)
|
2405
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
2406
|
+
end
|
2407
|
+
end
|
2408
|
+
|
2409
|
+
context "when config set not to raise error" do
|
2410
|
+
|
2411
|
+
let(:preference) do
|
2412
|
+
person.preferences.find(Moped::BSON::ObjectId.new)
|
2413
|
+
end
|
2414
|
+
|
2415
|
+
before do
|
2416
|
+
Mongoid.raise_not_found_error = false
|
2417
|
+
end
|
2418
|
+
|
2419
|
+
after do
|
2420
|
+
Mongoid.raise_not_found_error = true
|
2421
|
+
end
|
2422
|
+
|
2423
|
+
it "returns nil" do
|
2424
|
+
expect(preference).to be_nil
|
2425
|
+
end
|
2426
|
+
end
|
2427
|
+
end
|
2428
|
+
end
|
2429
|
+
|
2430
|
+
context "when providing an array of ids" do
|
2431
|
+
|
2432
|
+
context "when the ids match" do
|
2433
|
+
|
2434
|
+
let(:preferences) do
|
2435
|
+
person.preferences.find([ preference_one.id, preference_two.id ])
|
2436
|
+
end
|
2437
|
+
|
2438
|
+
it "returns the matching documents" do
|
2439
|
+
expect(preferences).to eq([ preference_one, preference_two ])
|
2440
|
+
end
|
2441
|
+
end
|
2442
|
+
|
2443
|
+
context "when the ids matche unreferenced documents" do
|
2444
|
+
|
2445
|
+
let(:preferences) do
|
2446
|
+
person.preferences.find(
|
2447
|
+
[ unrelated_pref.id, unrelated_pref_two.id ]
|
2448
|
+
)
|
2449
|
+
end
|
2450
|
+
|
2451
|
+
it "raises an error" do
|
2452
|
+
expect {
|
2453
|
+
preferences
|
2454
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
2455
|
+
end
|
2456
|
+
end
|
2457
|
+
|
2458
|
+
context "when the ids do not match" do
|
2459
|
+
|
2460
|
+
context "when config set to raise error" do
|
2461
|
+
|
2462
|
+
before do
|
2463
|
+
Mongoid.raise_not_found_error = true
|
2464
|
+
end
|
2465
|
+
|
2466
|
+
it "raises an error" do
|
2467
|
+
expect {
|
2468
|
+
person.preferences.find([ Moped::BSON::ObjectId.new ])
|
2469
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
2470
|
+
end
|
2471
|
+
end
|
2472
|
+
|
2473
|
+
context "when config set not to raise error" do
|
2474
|
+
|
2475
|
+
let(:preferences) do
|
2476
|
+
person.preferences.find([ Moped::BSON::ObjectId.new ])
|
2477
|
+
end
|
2478
|
+
|
2479
|
+
before do
|
2480
|
+
Mongoid.raise_not_found_error = false
|
2481
|
+
end
|
2482
|
+
|
2483
|
+
after do
|
2484
|
+
Mongoid.raise_not_found_error = true
|
2485
|
+
end
|
2486
|
+
|
2487
|
+
it "returns an empty array" do
|
2488
|
+
expect(preferences).to be_empty
|
2489
|
+
end
|
2490
|
+
end
|
2491
|
+
end
|
2492
|
+
end
|
2493
|
+
end
|
2494
|
+
end
|
2495
|
+
|
2496
|
+
describe "#find_or_create_by" do
|
2497
|
+
|
2498
|
+
context "when the relation is not polymorphic" do
|
2499
|
+
|
2500
|
+
let(:person) do
|
2501
|
+
Person.create
|
2502
|
+
end
|
2503
|
+
|
2504
|
+
let!(:preference) do
|
2505
|
+
person.preferences.create(name: "Testing")
|
2506
|
+
end
|
2507
|
+
|
2508
|
+
context "when the document exists" do
|
2509
|
+
|
2510
|
+
let(:found) do
|
2511
|
+
person.preferences.find_or_create_by(name: "Testing")
|
2512
|
+
end
|
2513
|
+
|
2514
|
+
it "returns the document" do
|
2515
|
+
expect(found).to eq(preference)
|
2516
|
+
end
|
2517
|
+
end
|
2518
|
+
|
2519
|
+
context "when the document does not exist" do
|
2520
|
+
|
2521
|
+
let(:found) do
|
2522
|
+
person.preferences.find_or_create_by(name: "Test")
|
2523
|
+
end
|
2524
|
+
|
2525
|
+
it "sets the new document attributes" do
|
2526
|
+
expect(found.name).to eq("Test")
|
2527
|
+
end
|
2528
|
+
|
2529
|
+
it "returns a newly persisted document" do
|
2530
|
+
expect(found).to be_persisted
|
2531
|
+
end
|
2532
|
+
end
|
2533
|
+
end
|
2534
|
+
end
|
2535
|
+
|
2536
|
+
describe "#find_or_initialize_by" do
|
2537
|
+
|
2538
|
+
context "when the relation is not polymorphic" do
|
2539
|
+
|
2540
|
+
let(:person) do
|
2541
|
+
Person.create
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
let!(:preference) do
|
2545
|
+
person.preferences.create(name: "Testing")
|
2546
|
+
end
|
2547
|
+
|
2548
|
+
context "when the document exists" do
|
2549
|
+
|
2550
|
+
let(:found) do
|
2551
|
+
person.preferences.find_or_initialize_by(name: "Testing")
|
2552
|
+
end
|
2553
|
+
|
2554
|
+
it "returns the document" do
|
2555
|
+
expect(found).to eq(preference)
|
2556
|
+
end
|
2557
|
+
end
|
2558
|
+
|
2559
|
+
context "when the document does not exist" do
|
2560
|
+
|
2561
|
+
let(:found) do
|
2562
|
+
person.preferences.find_or_initialize_by(name: "Test")
|
2563
|
+
end
|
2564
|
+
|
2565
|
+
it "sets the new document attributes" do
|
2566
|
+
expect(found.name).to eq("Test")
|
2567
|
+
end
|
2568
|
+
|
2569
|
+
it "returns a non persisted document" do
|
2570
|
+
expect(found).to_not be_persisted
|
2571
|
+
end
|
2572
|
+
end
|
2573
|
+
end
|
2574
|
+
end
|
2575
|
+
|
2576
|
+
describe ".foreign_key_suffix" do
|
2577
|
+
|
2578
|
+
it "returns _ids" do
|
2579
|
+
expect(described_class.foreign_key_suffix).to eq("_ids")
|
2580
|
+
end
|
2581
|
+
end
|
2582
|
+
|
2583
|
+
describe ".macro" do
|
2584
|
+
|
2585
|
+
it "returns has_and_belongs_to_many" do
|
2586
|
+
expect(described_class.macro).to eq(:has_and_belongs_to_many)
|
2587
|
+
end
|
2588
|
+
end
|
2589
|
+
|
2590
|
+
describe "#max" do
|
2591
|
+
|
2592
|
+
let(:person) do
|
2593
|
+
Person.create
|
2594
|
+
end
|
2595
|
+
|
2596
|
+
let(:preference_one) do
|
2597
|
+
Preference.create(ranking: 5)
|
2598
|
+
end
|
2599
|
+
|
2600
|
+
let(:preference_two) do
|
2601
|
+
Preference.create(ranking: 10)
|
2602
|
+
end
|
2603
|
+
|
2604
|
+
before do
|
2605
|
+
person.preferences.push(preference_one, preference_two)
|
2606
|
+
end
|
2607
|
+
|
2608
|
+
let(:max) do
|
2609
|
+
person.preferences.max do |a,b|
|
2610
|
+
a.ranking <=> b.ranking
|
2611
|
+
end
|
2612
|
+
end
|
2613
|
+
|
2614
|
+
it "returns the document with the max value of the supplied field" do
|
2615
|
+
expect(max).to eq(preference_two)
|
2616
|
+
end
|
2617
|
+
end
|
2618
|
+
|
2619
|
+
describe "#max_by" do
|
2620
|
+
|
2621
|
+
let(:person) do
|
2622
|
+
Person.create
|
2623
|
+
end
|
2624
|
+
|
2625
|
+
let(:preference_one) do
|
2626
|
+
Preference.create(ranking: 5)
|
2627
|
+
end
|
2628
|
+
|
2629
|
+
let(:preference_two) do
|
2630
|
+
Preference.create(ranking: 10)
|
2631
|
+
end
|
2632
|
+
|
2633
|
+
before do
|
2634
|
+
person.preferences.push(preference_one, preference_two)
|
2635
|
+
end
|
2636
|
+
|
2637
|
+
let(:max) do
|
2638
|
+
person.preferences.max_by(&:ranking)
|
2639
|
+
end
|
2640
|
+
|
2641
|
+
it "returns the document with the max value of the supplied field" do
|
2642
|
+
expect(max).to eq(preference_two)
|
2643
|
+
end
|
2644
|
+
end
|
2645
|
+
|
2646
|
+
describe "#method_missing" do
|
2647
|
+
|
2648
|
+
let!(:person) do
|
2649
|
+
Person.create
|
2650
|
+
end
|
2651
|
+
|
2652
|
+
let!(:preference_one) do
|
2653
|
+
person.preferences.create(name: "First", value: "Posting")
|
2654
|
+
end
|
2655
|
+
|
2656
|
+
let!(:preference_two) do
|
2657
|
+
person.preferences.create(name: "Second", value: "Testing")
|
2658
|
+
end
|
2659
|
+
|
2660
|
+
let!(:unrelated) do
|
2661
|
+
Preference.create(name: "Third")
|
2662
|
+
end
|
2663
|
+
|
2664
|
+
context "when providing a single criteria" do
|
2665
|
+
|
2666
|
+
let(:preferences) do
|
2667
|
+
person.preferences.where(name: "First")
|
2668
|
+
end
|
2669
|
+
|
2670
|
+
it "applies the criteria to the documents" do
|
2671
|
+
expect(preferences).to eq([ preference_one ])
|
2672
|
+
end
|
2673
|
+
end
|
2674
|
+
|
2675
|
+
context "when providing a criteria on id" do
|
2676
|
+
|
2677
|
+
let(:preferences) do
|
2678
|
+
person.preferences.where(_id: unrelated.id)
|
2679
|
+
end
|
2680
|
+
|
2681
|
+
it "does not return unrelated documents" do
|
2682
|
+
expect(preferences).to be_empty
|
2683
|
+
end
|
2684
|
+
end
|
2685
|
+
|
2686
|
+
context "when providing a criteria class method" do
|
2687
|
+
|
2688
|
+
let(:preferences) do
|
2689
|
+
person.preferences.posting
|
2690
|
+
end
|
2691
|
+
|
2692
|
+
it "applies the criteria to the documents" do
|
2693
|
+
expect(preferences).to eq([ preference_one ])
|
2694
|
+
end
|
2695
|
+
end
|
2696
|
+
|
2697
|
+
context "when chaining criteria" do
|
2698
|
+
|
2699
|
+
let(:preferences) do
|
2700
|
+
person.preferences.posting.where(:name.in => [ "First" ])
|
2701
|
+
end
|
2702
|
+
|
2703
|
+
it "applies the criteria to the documents" do
|
2704
|
+
expect(preferences).to eq([ preference_one ])
|
2705
|
+
end
|
2706
|
+
end
|
2707
|
+
|
2708
|
+
context "when delegating methods" do
|
2709
|
+
|
2710
|
+
describe "#distinct" do
|
2711
|
+
|
2712
|
+
let(:values) do
|
2713
|
+
person.preferences.distinct(:name)
|
2714
|
+
end
|
2715
|
+
|
2716
|
+
it "returns the distinct values for the fields" do
|
2717
|
+
expect(values).to include("First")
|
2718
|
+
expect(values).to include("Second")
|
2719
|
+
end
|
2720
|
+
|
2721
|
+
context "when the inverse relation is not defined" do
|
2722
|
+
|
2723
|
+
let!(:house) do
|
2724
|
+
person.houses.create(name: "Wayne Manor")
|
2725
|
+
end
|
2726
|
+
|
2727
|
+
it "returns the distinct values for the fields" do
|
2728
|
+
expect(person.houses.distinct(:name)).to eq([ house.name ])
|
2729
|
+
end
|
2730
|
+
end
|
2731
|
+
end
|
2732
|
+
end
|
2733
|
+
end
|
2734
|
+
|
2735
|
+
describe "#min" do
|
2736
|
+
|
2737
|
+
let(:person) do
|
2738
|
+
Person.create
|
2739
|
+
end
|
2740
|
+
|
2741
|
+
let(:preference_one) do
|
2742
|
+
Preference.create(ranking: 5)
|
2743
|
+
end
|
2744
|
+
|
2745
|
+
let(:preference_two) do
|
2746
|
+
Preference.create(ranking: 10)
|
2747
|
+
end
|
2748
|
+
|
2749
|
+
before do
|
2750
|
+
person.preferences.push(preference_one, preference_two)
|
2751
|
+
end
|
2752
|
+
|
2753
|
+
let(:min) do
|
2754
|
+
person.preferences.min do |a, b|
|
2755
|
+
a.ranking <=> b.ranking
|
2756
|
+
end
|
2757
|
+
end
|
2758
|
+
|
2759
|
+
it "returns the min value of the supplied field" do
|
2760
|
+
expect(min).to eq(preference_one)
|
2761
|
+
end
|
2762
|
+
end
|
2763
|
+
|
2764
|
+
describe "#min_by" do
|
2765
|
+
|
2766
|
+
let(:person) do
|
2767
|
+
Person.create
|
2768
|
+
end
|
2769
|
+
|
2770
|
+
let(:preference_one) do
|
2771
|
+
Preference.create(ranking: 5)
|
2772
|
+
end
|
2773
|
+
|
2774
|
+
let(:preference_two) do
|
2775
|
+
Preference.create(ranking: 10)
|
2776
|
+
end
|
2777
|
+
|
2778
|
+
before do
|
2779
|
+
person.preferences.push(preference_one, preference_two)
|
2780
|
+
end
|
2781
|
+
|
2782
|
+
let(:min) do
|
2783
|
+
person.preferences.min_by(&:ranking)
|
2784
|
+
end
|
2785
|
+
|
2786
|
+
it "returns the min value of the supplied field" do
|
2787
|
+
expect(min).to eq(preference_one)
|
2788
|
+
end
|
2789
|
+
end
|
2790
|
+
|
2791
|
+
describe "#nil?" do
|
2792
|
+
|
2793
|
+
it "returns false" do
|
2794
|
+
expect(Person.new.preferences).to_not be_nil
|
2795
|
+
end
|
2796
|
+
end
|
2797
|
+
|
2798
|
+
describe "#nullify_all" do
|
2799
|
+
|
2800
|
+
let(:person) do
|
2801
|
+
Person.create
|
2802
|
+
end
|
2803
|
+
|
2804
|
+
let!(:preference_one) do
|
2805
|
+
person.preferences.create(name: "One")
|
2806
|
+
end
|
2807
|
+
|
2808
|
+
let!(:preference_two) do
|
2809
|
+
person.preferences.create(name: "Two")
|
2810
|
+
end
|
2811
|
+
|
2812
|
+
before do
|
2813
|
+
person.preferences.nullify_all
|
2814
|
+
end
|
2815
|
+
|
2816
|
+
it "removes the foreign key from the base document" do
|
2817
|
+
[ preference_one, preference_two ].each do |preference|
|
2818
|
+
expect(person.preference_ids).to_not include(preference.id)
|
2819
|
+
end
|
2820
|
+
end
|
2821
|
+
|
2822
|
+
it "removes the foreign key from the target documents" do
|
2823
|
+
[ preference_one, preference_two ].each do |preference|
|
2824
|
+
expect(preference.person_ids).to_not include(person.id)
|
2825
|
+
end
|
2826
|
+
end
|
2827
|
+
|
2828
|
+
it "removes the reference from the base document" do
|
2829
|
+
[ preference_one, preference_two ].each do |preference|
|
2830
|
+
expect(person.preferences).to_not include(preference)
|
2831
|
+
end
|
2832
|
+
end
|
2833
|
+
|
2834
|
+
it "removes the reference from the target documents" do
|
2835
|
+
[ preference_one, preference_two ].each do |preference|
|
2836
|
+
expect(preference.people).to_not include(person)
|
2837
|
+
end
|
2838
|
+
end
|
2839
|
+
|
2840
|
+
it "saves the documents" do
|
2841
|
+
expect(preference_one.reload.people).to_not include(person)
|
2842
|
+
end
|
2843
|
+
end
|
2844
|
+
|
2845
|
+
describe "#respond_to?" do
|
2846
|
+
|
2847
|
+
let(:person) do
|
2848
|
+
Person.new
|
2849
|
+
end
|
2850
|
+
|
2851
|
+
let(:preferences) do
|
2852
|
+
person.preferences
|
2853
|
+
end
|
2854
|
+
|
2855
|
+
Array.public_instance_methods.each do |method|
|
2856
|
+
|
2857
|
+
context "when checking #{method}" do
|
2858
|
+
|
2859
|
+
it "returns true" do
|
2860
|
+
expect(preferences.respond_to?(method)).to be_true
|
2861
|
+
end
|
2862
|
+
end
|
2863
|
+
end
|
2864
|
+
|
2865
|
+
Mongoid::Relations::Referenced::Many.public_instance_methods.each do |method|
|
2866
|
+
|
2867
|
+
context "when checking #{method}" do
|
2868
|
+
|
2869
|
+
it "returns true" do
|
2870
|
+
expect(preferences.respond_to?(method)).to be_true
|
2871
|
+
end
|
2872
|
+
end
|
2873
|
+
end
|
2874
|
+
|
2875
|
+
Preference.scopes.keys.each do |method|
|
2876
|
+
|
2877
|
+
context "when checking #{method}" do
|
2878
|
+
|
2879
|
+
it "returns true" do
|
2880
|
+
expect(preferences.respond_to?(method)).to be_true
|
2881
|
+
end
|
2882
|
+
end
|
2883
|
+
end
|
2884
|
+
end
|
2885
|
+
|
2886
|
+
describe ".stores_foreign_key?" do
|
2887
|
+
|
2888
|
+
it "returns true" do
|
2889
|
+
expect(described_class.stores_foreign_key?).to be_true
|
2890
|
+
end
|
2891
|
+
end
|
2892
|
+
|
2893
|
+
describe "#scoped" do
|
2894
|
+
|
2895
|
+
let(:person) do
|
2896
|
+
Person.new
|
2897
|
+
end
|
2898
|
+
|
2899
|
+
let(:scoped) do
|
2900
|
+
person.preferences.scoped
|
2901
|
+
end
|
2902
|
+
|
2903
|
+
it "returns the relation criteria" do
|
2904
|
+
expect(scoped).to be_a(Mongoid::Criteria)
|
2905
|
+
end
|
2906
|
+
|
2907
|
+
it "returns with an empty selector" do
|
2908
|
+
expect(scoped.selector).to eq({ "$and" => [{ "_id" => { "$in" => [] }}]})
|
2909
|
+
end
|
2910
|
+
end
|
2911
|
+
|
2912
|
+
[ :size, :length ].each do |method|
|
2913
|
+
|
2914
|
+
describe "##{method}" do
|
2915
|
+
|
2916
|
+
let(:person) do
|
2917
|
+
Person.create
|
2918
|
+
end
|
2919
|
+
|
2920
|
+
context "when documents have been persisted" do
|
2921
|
+
|
2922
|
+
let!(:preference) do
|
2923
|
+
person.preferences.create(name: "Testing")
|
2924
|
+
end
|
2925
|
+
|
2926
|
+
it "returns the number of documents" do
|
2927
|
+
expect(person.preferences.send(method)).to eq(1)
|
2928
|
+
end
|
2929
|
+
end
|
2930
|
+
|
2931
|
+
context "when documents have not been persisted" do
|
2932
|
+
|
2933
|
+
before do
|
2934
|
+
person.preferences.build(name: "Test")
|
2935
|
+
person.preferences.create(name: "Test 2")
|
2936
|
+
end
|
2937
|
+
|
2938
|
+
it "returns the total number of documents" do
|
2939
|
+
expect(person.preferences.send(method)).to eq(2)
|
2940
|
+
end
|
2941
|
+
end
|
2942
|
+
end
|
2943
|
+
end
|
2944
|
+
|
2945
|
+
describe "#unscoped" do
|
2946
|
+
|
2947
|
+
context "when the relation has no default scope" do
|
2948
|
+
|
2949
|
+
let!(:person) do
|
2950
|
+
Person.create
|
2951
|
+
end
|
2952
|
+
|
2953
|
+
let!(:preference_one) do
|
2954
|
+
person.preferences.create(name: "first")
|
2955
|
+
end
|
2956
|
+
|
2957
|
+
let!(:preference_two) do
|
2958
|
+
Preference.create(name: "second")
|
2959
|
+
end
|
2960
|
+
|
2961
|
+
let(:unscoped) do
|
2962
|
+
person.preferences.unscoped
|
2963
|
+
end
|
2964
|
+
|
2965
|
+
it "returns only the associated documents" do
|
2966
|
+
expect(unscoped).to eq([ preference_one ])
|
2967
|
+
end
|
2968
|
+
end
|
2969
|
+
|
2970
|
+
context "when the relation has a default scope" do
|
2971
|
+
|
2972
|
+
let!(:person) do
|
2973
|
+
Person.create
|
2974
|
+
end
|
2975
|
+
|
2976
|
+
let!(:house_one) do
|
2977
|
+
person.houses.create(name: "first")
|
2978
|
+
end
|
2979
|
+
|
2980
|
+
let!(:house_two) do
|
2981
|
+
House.create(name: "second")
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
let(:unscoped) do
|
2985
|
+
person.houses.unscoped
|
2986
|
+
end
|
2987
|
+
|
2988
|
+
it "only returns associated documents" do
|
2989
|
+
expect(unscoped).to eq([ house_one ])
|
2990
|
+
end
|
2991
|
+
|
2992
|
+
it "removes the default scoping options" do
|
2993
|
+
expect(unscoped.options).to eq({})
|
2994
|
+
end
|
2995
|
+
end
|
2996
|
+
end
|
2997
|
+
|
2998
|
+
describe ".valid_options" do
|
2999
|
+
|
3000
|
+
it "returns the valid options" do
|
3001
|
+
expect(described_class.valid_options).to eq(
|
3002
|
+
[
|
3003
|
+
:after_add,
|
3004
|
+
:after_remove,
|
3005
|
+
:autosave,
|
3006
|
+
:before_add,
|
3007
|
+
:before_remove,
|
3008
|
+
:dependent,
|
3009
|
+
:foreign_key,
|
3010
|
+
:index,
|
3011
|
+
:order,
|
3012
|
+
:primary_key
|
3013
|
+
]
|
3014
|
+
)
|
3015
|
+
end
|
3016
|
+
end
|
3017
|
+
|
3018
|
+
describe ".validation_default" do
|
3019
|
+
|
3020
|
+
it "returns true" do
|
3021
|
+
expect(described_class.validation_default).to be_true
|
3022
|
+
end
|
3023
|
+
end
|
3024
|
+
|
3025
|
+
context "when setting the ids directly after the documents" do
|
3026
|
+
|
3027
|
+
let!(:person) do
|
3028
|
+
Person.create!(title: "The Boss")
|
3029
|
+
end
|
3030
|
+
|
3031
|
+
let!(:girlfriend_house) do
|
3032
|
+
House.create!(name: "Girlfriend")
|
3033
|
+
end
|
3034
|
+
|
3035
|
+
let!(:wife_house) do
|
3036
|
+
House.create!(name: "Wife")
|
3037
|
+
end
|
3038
|
+
|
3039
|
+
let!(:exwife_house) do
|
3040
|
+
House.create!(name: "Ex-Wife")
|
3041
|
+
end
|
3042
|
+
|
3043
|
+
before do
|
3044
|
+
person.update_attributes(
|
3045
|
+
houses: [ wife_house, exwife_house, girlfriend_house ]
|
3046
|
+
)
|
3047
|
+
person.update_attributes(house_ids: [ girlfriend_house.id ])
|
3048
|
+
end
|
3049
|
+
|
3050
|
+
context "when reloading" do
|
3051
|
+
|
3052
|
+
it "properly sets the references" do
|
3053
|
+
expect(person.houses(true)).to eq([ girlfriend_house ])
|
3054
|
+
end
|
3055
|
+
end
|
3056
|
+
end
|
3057
|
+
|
3058
|
+
context "when setting both sides in a single call" do
|
3059
|
+
|
3060
|
+
context "when the documents are new" do
|
3061
|
+
|
3062
|
+
let(:user) do
|
3063
|
+
User.new(name: "testing")
|
3064
|
+
end
|
3065
|
+
|
3066
|
+
let(:business) do
|
3067
|
+
Business.new(name: "serious", owners: [ user ])
|
3068
|
+
end
|
3069
|
+
|
3070
|
+
before do
|
3071
|
+
user.businesses = [ business ]
|
3072
|
+
end
|
3073
|
+
|
3074
|
+
it "sets the businesses" do
|
3075
|
+
expect(user.businesses).to eq([ business ])
|
3076
|
+
end
|
3077
|
+
|
3078
|
+
it "sets the inverse users" do
|
3079
|
+
expect(user.businesses.first.owners.first).to eq(user)
|
3080
|
+
end
|
3081
|
+
|
3082
|
+
it "sets the inverse businesses" do
|
3083
|
+
expect(business.owners).to eq([ user ])
|
3084
|
+
end
|
3085
|
+
end
|
3086
|
+
|
3087
|
+
context "when one side is persisted" do
|
3088
|
+
|
3089
|
+
let!(:user) do
|
3090
|
+
User.new(name: "testing")
|
3091
|
+
end
|
3092
|
+
|
3093
|
+
let!(:business) do
|
3094
|
+
Business.create(name: "serious", owners: [ user ])
|
3095
|
+
end
|
3096
|
+
|
3097
|
+
before do
|
3098
|
+
user.businesses = [ business ]
|
3099
|
+
end
|
3100
|
+
|
3101
|
+
it "sets the businesses" do
|
3102
|
+
expect(user.businesses).to eq([ business ])
|
3103
|
+
end
|
3104
|
+
|
3105
|
+
it "sets the inverse users" do
|
3106
|
+
expect(user.businesses.first.owners.first).to eq(user)
|
3107
|
+
end
|
3108
|
+
|
3109
|
+
it "sets the inverse businesses" do
|
3110
|
+
expect(business.owners).to eq([ user ])
|
3111
|
+
end
|
3112
|
+
|
3113
|
+
context "when reloading" do
|
3114
|
+
|
3115
|
+
before do
|
3116
|
+
user.reload
|
3117
|
+
business.reload
|
3118
|
+
end
|
3119
|
+
|
3120
|
+
it "persists the businesses" do
|
3121
|
+
expect(user.businesses).to eq([ business ])
|
3122
|
+
end
|
3123
|
+
|
3124
|
+
it "persists the inverse users" do
|
3125
|
+
expect(user.businesses.first.owners.first).to eq(user)
|
3126
|
+
end
|
3127
|
+
|
3128
|
+
it "persists the inverse businesses" do
|
3129
|
+
expect(business.owners).to eq([ user ])
|
3130
|
+
end
|
3131
|
+
end
|
3132
|
+
end
|
3133
|
+
|
3134
|
+
context "when the documents are persisted" do
|
3135
|
+
|
3136
|
+
let(:user) do
|
3137
|
+
User.create(name: "tst")
|
3138
|
+
end
|
3139
|
+
|
3140
|
+
let(:business) do
|
3141
|
+
Business.create(name: "srs", owners: [ user ])
|
3142
|
+
end
|
3143
|
+
|
3144
|
+
before do
|
3145
|
+
user.businesses = [ business ]
|
3146
|
+
end
|
3147
|
+
|
3148
|
+
it "sets the businesses" do
|
3149
|
+
expect(user.businesses).to eq([ business ])
|
3150
|
+
end
|
3151
|
+
|
3152
|
+
it "sets the inverse users" do
|
3153
|
+
expect(user.businesses.first.owners.first).to eq(user)
|
3154
|
+
end
|
3155
|
+
|
3156
|
+
it "sets the inverse businesses" do
|
3157
|
+
expect(business.owners).to eq([ user ])
|
3158
|
+
end
|
3159
|
+
|
3160
|
+
context "when reloading" do
|
3161
|
+
|
3162
|
+
before do
|
3163
|
+
user.reload
|
3164
|
+
business.reload
|
3165
|
+
end
|
3166
|
+
|
3167
|
+
it "persists the businesses" do
|
3168
|
+
expect(user.businesses).to eq([ business ])
|
3169
|
+
end
|
3170
|
+
|
3171
|
+
it "persists the inverse users" do
|
3172
|
+
expect(user.businesses.first.owners.first).to eq(user)
|
3173
|
+
end
|
3174
|
+
|
3175
|
+
it "persists the inverse businesses" do
|
3176
|
+
expect(business.owners).to eq([ user ])
|
3177
|
+
end
|
3178
|
+
end
|
3179
|
+
end
|
3180
|
+
end
|
3181
|
+
|
3182
|
+
context "when binding the relation multiple times" do
|
3183
|
+
|
3184
|
+
let(:person) do
|
3185
|
+
Person.create
|
3186
|
+
end
|
3187
|
+
|
3188
|
+
let(:preference) do
|
3189
|
+
person.preferences.create(name: "testing")
|
3190
|
+
end
|
3191
|
+
|
3192
|
+
before do
|
3193
|
+
2.times do
|
3194
|
+
person.preferences.each do |preference|
|
3195
|
+
expect(preference.person_ids).to eq([ person.id ])
|
3196
|
+
end
|
3197
|
+
end
|
3198
|
+
end
|
3199
|
+
|
3200
|
+
it "does not duplicate foreign keys" do
|
3201
|
+
expect(person.preference_ids).to eq([ preference.id ])
|
3202
|
+
end
|
3203
|
+
end
|
3204
|
+
|
3205
|
+
context "when the association has order criteria" do
|
3206
|
+
|
3207
|
+
let(:person) do
|
3208
|
+
Person.create
|
3209
|
+
end
|
3210
|
+
|
3211
|
+
let(:preference_one) do
|
3212
|
+
OrderedPreference.create(name: 'preference-1', value: 10)
|
3213
|
+
end
|
3214
|
+
|
3215
|
+
let(:preference_two) do
|
3216
|
+
OrderedPreference.create(name: 'preference-2', value: 20)
|
3217
|
+
end
|
3218
|
+
|
3219
|
+
let(:preference_three) do
|
3220
|
+
OrderedPreference.create(name: 'preference-3', value: 20)
|
3221
|
+
end
|
3222
|
+
|
3223
|
+
before do
|
3224
|
+
person.ordered_preferences.nullify_all
|
3225
|
+
person.ordered_preferences.push(preference_one, preference_two, preference_three)
|
3226
|
+
end
|
3227
|
+
|
3228
|
+
it "orders the documents" do
|
3229
|
+
expect(person.ordered_preferences(true)).to eq(
|
3230
|
+
[preference_two, preference_three, preference_one]
|
3231
|
+
)
|
3232
|
+
end
|
3233
|
+
|
3234
|
+
it "chains default criteria with additional" do
|
3235
|
+
expect(person.ordered_preferences.order_by(:name.desc).to_a).to eq(
|
3236
|
+
[preference_three, preference_two, preference_one]
|
3237
|
+
)
|
3238
|
+
end
|
3239
|
+
end
|
3240
|
+
|
3241
|
+
context "when the parent is not a new record and freshly loaded" do
|
3242
|
+
|
3243
|
+
let(:person) do
|
3244
|
+
Person.create
|
3245
|
+
end
|
3246
|
+
|
3247
|
+
let(:preference) do
|
3248
|
+
Preference.new
|
3249
|
+
end
|
3250
|
+
|
3251
|
+
before do
|
3252
|
+
person.preferences = [ preference ]
|
3253
|
+
person.save
|
3254
|
+
person.reload
|
3255
|
+
person.preferences = nil
|
3256
|
+
end
|
3257
|
+
|
3258
|
+
it "sets the relation to an empty array" do
|
3259
|
+
expect(person.preferences).to be_empty
|
3260
|
+
end
|
3261
|
+
|
3262
|
+
it "removes the foreign key values" do
|
3263
|
+
expect(person.preference_ids).to be_empty
|
3264
|
+
end
|
3265
|
+
|
3266
|
+
it "does not delete the target from the database" do
|
3267
|
+
expect {
|
3268
|
+
preference.reload
|
3269
|
+
}.not_to raise_error
|
3270
|
+
end
|
3271
|
+
end
|
3272
|
+
|
3273
|
+
context "when reloading the relation" do
|
3274
|
+
|
3275
|
+
let!(:person) do
|
3276
|
+
Person.create
|
3277
|
+
end
|
3278
|
+
|
3279
|
+
let!(:preference_one) do
|
3280
|
+
Preference.create(name: "one")
|
3281
|
+
end
|
3282
|
+
|
3283
|
+
let!(:preference_two) do
|
3284
|
+
Preference.create(name: "two")
|
3285
|
+
end
|
3286
|
+
|
3287
|
+
before do
|
3288
|
+
person.preferences << preference_one
|
3289
|
+
end
|
3290
|
+
|
3291
|
+
context "when the relation references the same documents" do
|
3292
|
+
|
3293
|
+
before do
|
3294
|
+
Preference.collection.find({ _id: preference_one.id }).
|
3295
|
+
update({ "$set" => { name: "reloaded" }})
|
3296
|
+
end
|
3297
|
+
|
3298
|
+
let(:reloaded) do
|
3299
|
+
person.preferences(true)
|
3300
|
+
end
|
3301
|
+
|
3302
|
+
it "reloads the document from the database" do
|
3303
|
+
expect(reloaded.first.name).to eq("reloaded")
|
3304
|
+
end
|
3305
|
+
end
|
3306
|
+
|
3307
|
+
context "when the relation references different documents" do
|
3308
|
+
|
3309
|
+
before do
|
3310
|
+
person.preferences << preference_two
|
3311
|
+
end
|
3312
|
+
|
3313
|
+
let(:reloaded) do
|
3314
|
+
person.preferences(true)
|
3315
|
+
end
|
3316
|
+
|
3317
|
+
it "reloads the new document from the database" do
|
3318
|
+
expect(reloaded).to eq([ preference_one, preference_two ])
|
3319
|
+
end
|
3320
|
+
end
|
3321
|
+
end
|
3322
|
+
|
3323
|
+
context "when adding to a relation via a field setter" do
|
3324
|
+
|
3325
|
+
context "when the document is new" do
|
3326
|
+
|
3327
|
+
let!(:person) do
|
3328
|
+
Person.create(preference_names: "one, two")
|
3329
|
+
end
|
3330
|
+
|
3331
|
+
let(:preference_one) do
|
3332
|
+
person.reload.preferences.first
|
3333
|
+
end
|
3334
|
+
|
3335
|
+
let(:preference_two) do
|
3336
|
+
person.reload.preferences.last
|
3337
|
+
end
|
3338
|
+
|
3339
|
+
it "persists the first preference" do
|
3340
|
+
expect(preference_one).to_not be_nil
|
3341
|
+
end
|
3342
|
+
|
3343
|
+
it "sets the first inverse" do
|
3344
|
+
expect(preference_one.people).to eq([ person ])
|
3345
|
+
end
|
3346
|
+
|
3347
|
+
it "persists the second preference" do
|
3348
|
+
expect(preference_two).to_not be_nil
|
3349
|
+
end
|
3350
|
+
|
3351
|
+
it "sets the second inverse keys" do
|
3352
|
+
expect(preference_two.people).to eq([ person ])
|
3353
|
+
end
|
3354
|
+
end
|
3355
|
+
end
|
3356
|
+
|
3357
|
+
context "when changing the order of existing ids" do
|
3358
|
+
|
3359
|
+
let(:person) do
|
3360
|
+
Person.new
|
3361
|
+
end
|
3362
|
+
|
3363
|
+
let(:preference_one) do
|
3364
|
+
Preference.create(name: "one")
|
3365
|
+
end
|
3366
|
+
|
3367
|
+
let(:preference_two) do
|
3368
|
+
Preference.create(name: "two")
|
3369
|
+
end
|
3370
|
+
|
3371
|
+
before do
|
3372
|
+
person.preference_ids = [ preference_one.id, preference_two.id ]
|
3373
|
+
person.save
|
3374
|
+
end
|
3375
|
+
|
3376
|
+
context "and the order is changed" do
|
3377
|
+
|
3378
|
+
before do
|
3379
|
+
person.preference_ids = [ preference_two.id, preference_one.id ]
|
3380
|
+
person.save
|
3381
|
+
end
|
3382
|
+
|
3383
|
+
let(:reloaded) do
|
3384
|
+
Person.find(person.id)
|
3385
|
+
end
|
3386
|
+
|
3387
|
+
it "persists the change in id order" do
|
3388
|
+
expect(reloaded.preference_ids).to eq(
|
3389
|
+
[ preference_two.id, preference_one.id ]
|
3390
|
+
)
|
3391
|
+
end
|
3392
|
+
end
|
3393
|
+
|
3394
|
+
context "and the order is changed and an element is added" do
|
3395
|
+
|
3396
|
+
let(:preference_three) do
|
3397
|
+
Preference.create(name: "three")
|
3398
|
+
end
|
3399
|
+
|
3400
|
+
before do
|
3401
|
+
person.preference_ids =
|
3402
|
+
[ preference_two.id, preference_one.id, preference_three.id ]
|
3403
|
+
person.save
|
3404
|
+
end
|
3405
|
+
|
3406
|
+
let(:reloaded) do
|
3407
|
+
Person.find(person.id)
|
3408
|
+
end
|
3409
|
+
|
3410
|
+
it "also persists the change in id order" do
|
3411
|
+
expect(reloaded.preference_ids).to eq(
|
3412
|
+
[ preference_two.id, preference_one.id, preference_three.id ]
|
3413
|
+
)
|
3414
|
+
end
|
3415
|
+
end
|
3416
|
+
|
3417
|
+
context "and the order is changed and an element is removed" do
|
3418
|
+
|
3419
|
+
let(:preference_three) do
|
3420
|
+
Preference.create(name: "three")
|
3421
|
+
end
|
3422
|
+
|
3423
|
+
before do
|
3424
|
+
person.preference_ids =
|
3425
|
+
[ preference_one.id, preference_two.id, preference_three.id ]
|
3426
|
+
person.save
|
3427
|
+
person.preference_ids =
|
3428
|
+
[ preference_three.id, preference_two.id ]
|
3429
|
+
person.save
|
3430
|
+
end
|
3431
|
+
|
3432
|
+
let(:reloaded) do
|
3433
|
+
Person.find(person.id)
|
3434
|
+
end
|
3435
|
+
|
3436
|
+
it "also persists the change in id order" do
|
3437
|
+
expect(reloaded.preference_ids).to eq(
|
3438
|
+
[ preference_three.id, preference_two.id ]
|
3439
|
+
)
|
3440
|
+
end
|
3441
|
+
end
|
3442
|
+
end
|
3443
|
+
|
3444
|
+
context "when adding a document" do
|
3445
|
+
|
3446
|
+
let(:person) do
|
3447
|
+
Person.new
|
3448
|
+
end
|
3449
|
+
|
3450
|
+
let(:preference_one) do
|
3451
|
+
Preference.new
|
3452
|
+
end
|
3453
|
+
|
3454
|
+
let(:first_add) do
|
3455
|
+
person.preferences.push(preference_one)
|
3456
|
+
end
|
3457
|
+
|
3458
|
+
context "when chaining a second add" do
|
3459
|
+
|
3460
|
+
let(:preference_two) do
|
3461
|
+
Preference.new
|
3462
|
+
end
|
3463
|
+
|
3464
|
+
let(:result) do
|
3465
|
+
first_add.push(preference_two)
|
3466
|
+
end
|
3467
|
+
|
3468
|
+
it "adds both documents" do
|
3469
|
+
expect(result).to eq([ preference_one, preference_two ])
|
3470
|
+
end
|
3471
|
+
end
|
3472
|
+
end
|
3473
|
+
|
3474
|
+
context "when setting the relation via the foreign key" do
|
3475
|
+
|
3476
|
+
context "when the relation exists" do
|
3477
|
+
|
3478
|
+
let!(:person) do
|
3479
|
+
Person.create
|
3480
|
+
end
|
3481
|
+
|
3482
|
+
let!(:pref_one) do
|
3483
|
+
person.preferences.create
|
3484
|
+
end
|
3485
|
+
|
3486
|
+
let!(:pref_two) do
|
3487
|
+
Preference.create
|
3488
|
+
end
|
3489
|
+
|
3490
|
+
before do
|
3491
|
+
person.preference_ids = [ pref_two.id ]
|
3492
|
+
end
|
3493
|
+
|
3494
|
+
it "sets the new documents on the relation" do
|
3495
|
+
expect(person.preferences).to eq([ pref_two ])
|
3496
|
+
end
|
3497
|
+
end
|
3498
|
+
end
|
3499
|
+
|
3500
|
+
context "when using a different primary key" do
|
3501
|
+
|
3502
|
+
let(:dog) do
|
3503
|
+
Dog.create(name: 'Doggie')
|
3504
|
+
end
|
3505
|
+
|
3506
|
+
let(:cat) do
|
3507
|
+
Cat.create(name: 'Kitty')
|
3508
|
+
end
|
3509
|
+
|
3510
|
+
let(:fire_hydrant) do
|
3511
|
+
FireHydrant.create(location: '221B Baker Street')
|
3512
|
+
end
|
3513
|
+
|
3514
|
+
context "when adding to a one-way many to many" do
|
3515
|
+
|
3516
|
+
before do
|
3517
|
+
fire_hydrant.cats.push(cat)
|
3518
|
+
end
|
3519
|
+
|
3520
|
+
it "adds the pk value to the fk set" do
|
3521
|
+
expect(fire_hydrant.cat_ids).to eq([cat.name])
|
3522
|
+
end
|
3523
|
+
end
|
3524
|
+
|
3525
|
+
context "when adding to a two-way many to many" do
|
3526
|
+
|
3527
|
+
before do
|
3528
|
+
fire_hydrant.dogs.push(dog)
|
3529
|
+
end
|
3530
|
+
|
3531
|
+
it "adds the pk value to the fk set" do
|
3532
|
+
expect(fire_hydrant.dog_ids).to eq([dog.name])
|
3533
|
+
end
|
3534
|
+
|
3535
|
+
it "adds the base pk value to the inverse fk set" do
|
3536
|
+
expect(dog.fire_hydrant_ids).to eq([fire_hydrant.location])
|
3537
|
+
end
|
3538
|
+
end
|
3539
|
+
|
3540
|
+
context "when deleting from a two-way many to many" do
|
3541
|
+
|
3542
|
+
before do
|
3543
|
+
dog.fire_hydrants.push(fire_hydrant)
|
3544
|
+
fire_hydrant.dogs.delete(dog)
|
3545
|
+
end
|
3546
|
+
|
3547
|
+
it "removes the pk value from the fk set" do
|
3548
|
+
expect(fire_hydrant.dog_ids).to eq([])
|
3549
|
+
end
|
3550
|
+
|
3551
|
+
it "removes the base pk value from the inverse fk set" do
|
3552
|
+
expect(dog.fire_hydrant_ids).to eq([])
|
3553
|
+
end
|
3554
|
+
end
|
3555
|
+
end
|
3556
|
+
end
|