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