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