mongoid_rails4 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +3213 -0
- data/LICENSE +20 -0
- data/README.md +62 -0
- data/Rakefile +35 -0
- data/lib/config/locales/en.yml +448 -0
- data/lib/mongoid.rb +104 -0
- data/lib/mongoid/atomic.rb +384 -0
- data/lib/mongoid/atomic/modifiers.rb +317 -0
- data/lib/mongoid/atomic/paths.rb +3 -0
- data/lib/mongoid/atomic/paths/embedded.rb +28 -0
- data/lib/mongoid/atomic/paths/embedded/many.rb +44 -0
- data/lib/mongoid/atomic/paths/embedded/one.rb +43 -0
- data/lib/mongoid/atomic/paths/root.rb +39 -0
- data/lib/mongoid/attributes.rb +284 -0
- data/lib/mongoid/attributes/dynamic.rb +154 -0
- data/lib/mongoid/attributes/nested.rb +82 -0
- data/lib/mongoid/attributes/processing.rb +147 -0
- data/lib/mongoid/attributes/readonly.rb +56 -0
- data/lib/mongoid/changeable.rb +379 -0
- data/lib/mongoid/composable.rb +104 -0
- data/lib/mongoid/config.rb +263 -0
- data/lib/mongoid/config/environment.rb +44 -0
- data/lib/mongoid/config/options.rb +74 -0
- data/lib/mongoid/config/validators.rb +3 -0
- data/lib/mongoid/config/validators/option.rb +25 -0
- data/lib/mongoid/config/validators/session.rb +140 -0
- data/lib/mongoid/contextual.rb +54 -0
- data/lib/mongoid/contextual/aggregable/memory.rb +109 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +147 -0
- data/lib/mongoid/contextual/atomic.rb +180 -0
- data/lib/mongoid/contextual/command.rb +61 -0
- data/lib/mongoid/contextual/eager.rb +158 -0
- data/lib/mongoid/contextual/find_and_modify.rb +69 -0
- data/lib/mongoid/contextual/geo_near.rb +238 -0
- data/lib/mongoid/contextual/map_reduce.rb +324 -0
- data/lib/mongoid/contextual/memory.rb +440 -0
- data/lib/mongoid/contextual/mongo.rb +676 -0
- data/lib/mongoid/contextual/queryable.rb +25 -0
- data/lib/mongoid/contextual/text_search.rb +180 -0
- data/lib/mongoid/copyable.rb +67 -0
- data/lib/mongoid/criteria.rb +562 -0
- data/lib/mongoid/criteria/findable.rb +179 -0
- data/lib/mongoid/criteria/inspectable.rb +25 -0
- data/lib/mongoid/criteria/marshalable.rb +50 -0
- data/lib/mongoid/criteria/modifiable.rb +189 -0
- data/lib/mongoid/criteria/scopable.rb +158 -0
- data/lib/mongoid/document.rb +361 -0
- data/lib/mongoid/equality.rb +66 -0
- data/lib/mongoid/errors.rb +40 -0
- data/lib/mongoid/errors/ambiguous_relationship.rb +51 -0
- data/lib/mongoid/errors/callback.rb +25 -0
- data/lib/mongoid/errors/delete_restriction.rb +29 -0
- data/lib/mongoid/errors/document_not_found.rb +111 -0
- data/lib/mongoid/errors/eager_load.rb +22 -0
- data/lib/mongoid/errors/invalid_collection.rb +18 -0
- data/lib/mongoid/errors/invalid_config_option.rb +27 -0
- data/lib/mongoid/errors/invalid_field.rb +64 -0
- data/lib/mongoid/errors/invalid_field_option.rb +35 -0
- data/lib/mongoid/errors/invalid_find.rb +19 -0
- data/lib/mongoid/errors/invalid_includes.rb +32 -0
- data/lib/mongoid/errors/invalid_index.rb +28 -0
- data/lib/mongoid/errors/invalid_options.rb +28 -0
- data/lib/mongoid/errors/invalid_path.rb +21 -0
- data/lib/mongoid/errors/invalid_scope.rb +24 -0
- data/lib/mongoid/errors/invalid_set_polymorphic_relation.rb +38 -0
- data/lib/mongoid/errors/invalid_storage_options.rb +27 -0
- data/lib/mongoid/errors/invalid_time.rb +22 -0
- data/lib/mongoid/errors/inverse_not_found.rb +29 -0
- data/lib/mongoid/errors/mixed_relations.rb +32 -0
- data/lib/mongoid/errors/mixed_session_configuration.rb +28 -0
- data/lib/mongoid/errors/mongoid_error.rb +92 -0
- data/lib/mongoid/errors/nested_attributes_metadata_not_found.rb +28 -0
- data/lib/mongoid/errors/no_default_session.rb +23 -0
- data/lib/mongoid/errors/no_environment.rb +19 -0
- data/lib/mongoid/errors/no_map_reduce_output.rb +24 -0
- data/lib/mongoid/errors/no_metadata.rb +21 -0
- data/lib/mongoid/errors/no_parent.rb +24 -0
- data/lib/mongoid/errors/no_session_config.rb +22 -0
- data/lib/mongoid/errors/no_session_database.rb +27 -0
- data/lib/mongoid/errors/no_session_hosts.rb +27 -0
- data/lib/mongoid/errors/no_sessions_config.rb +20 -0
- data/lib/mongoid/errors/readonly_attribute.rb +25 -0
- data/lib/mongoid/errors/scope_overwrite.rb +21 -0
- data/lib/mongoid/errors/too_many_nested_attribute_records.rb +20 -0
- data/lib/mongoid/errors/unknown_attribute.rb +25 -0
- data/lib/mongoid/errors/unsaved_document.rb +19 -0
- data/lib/mongoid/errors/unsupported_javascript.rb +27 -0
- data/lib/mongoid/errors/validations.rb +29 -0
- data/lib/mongoid/evolvable.rb +19 -0
- data/lib/mongoid/extensions.rb +35 -0
- data/lib/mongoid/extensions/array.rb +180 -0
- data/lib/mongoid/extensions/big_decimal.rb +69 -0
- data/lib/mongoid/extensions/boolean.rb +21 -0
- data/lib/mongoid/extensions/date.rb +77 -0
- data/lib/mongoid/extensions/date_time.rb +73 -0
- data/lib/mongoid/extensions/false_class.rb +38 -0
- data/lib/mongoid/extensions/float.rb +56 -0
- data/lib/mongoid/extensions/hash.rb +209 -0
- data/lib/mongoid/extensions/integer.rb +67 -0
- data/lib/mongoid/extensions/module.rb +28 -0
- data/lib/mongoid/extensions/nil_class.rb +33 -0
- data/lib/mongoid/extensions/object.rb +274 -0
- data/lib/mongoid/extensions/object_id.rb +54 -0
- data/lib/mongoid/extensions/range.rb +79 -0
- data/lib/mongoid/extensions/regexp.rb +27 -0
- data/lib/mongoid/extensions/set.rb +55 -0
- data/lib/mongoid/extensions/string.rb +199 -0
- data/lib/mongoid/extensions/symbol.rb +54 -0
- data/lib/mongoid/extensions/time.rb +88 -0
- data/lib/mongoid/extensions/time_with_zone.rb +56 -0
- data/lib/mongoid/extensions/true_class.rb +38 -0
- data/lib/mongoid/factory.rb +46 -0
- data/lib/mongoid/fields.rb +542 -0
- data/lib/mongoid/fields/foreign_key.rb +174 -0
- data/lib/mongoid/fields/localized.rb +73 -0
- data/lib/mongoid/fields/standard.rb +273 -0
- data/lib/mongoid/fields/validators.rb +2 -0
- data/lib/mongoid/fields/validators/macro.rb +92 -0
- data/lib/mongoid/findable.rb +133 -0
- data/lib/mongoid/identity_map.rb +163 -0
- data/lib/mongoid/indexable.rb +147 -0
- data/lib/mongoid/indexable/specification.rb +115 -0
- data/lib/mongoid/indexable/validators/options.rb +103 -0
- data/lib/mongoid/inspectable.rb +59 -0
- data/lib/mongoid/interceptable.rb +265 -0
- data/lib/mongoid/loggable.rb +69 -0
- data/lib/mongoid/matchable.rb +152 -0
- data/lib/mongoid/matchable/all.rb +27 -0
- data/lib/mongoid/matchable/and.rb +30 -0
- data/lib/mongoid/matchable/default.rb +72 -0
- data/lib/mongoid/matchable/exists.rb +23 -0
- data/lib/mongoid/matchable/gt.rb +21 -0
- data/lib/mongoid/matchable/gte.rb +21 -0
- data/lib/mongoid/matchable/in.rb +24 -0
- data/lib/mongoid/matchable/lt.rb +21 -0
- data/lib/mongoid/matchable/lte.rb +21 -0
- data/lib/mongoid/matchable/ne.rb +21 -0
- data/lib/mongoid/matchable/nin.rb +21 -0
- data/lib/mongoid/matchable/or.rb +33 -0
- data/lib/mongoid/matchable/size.rb +21 -0
- data/lib/mongoid/persistable.rb +207 -0
- data/lib/mongoid/persistable/creatable.rb +189 -0
- data/lib/mongoid/persistable/deletable.rb +149 -0
- data/lib/mongoid/persistable/destroyable.rb +55 -0
- data/lib/mongoid/persistable/incrementable.rb +36 -0
- data/lib/mongoid/persistable/logical.rb +38 -0
- data/lib/mongoid/persistable/poppable.rb +39 -0
- data/lib/mongoid/persistable/pullable.rb +55 -0
- data/lib/mongoid/persistable/pushable.rb +62 -0
- data/lib/mongoid/persistable/renamable.rb +35 -0
- data/lib/mongoid/persistable/savable.rb +52 -0
- data/lib/mongoid/persistable/settable.rb +33 -0
- data/lib/mongoid/persistable/unsettable.rb +36 -0
- data/lib/mongoid/persistable/updatable.rb +151 -0
- data/lib/mongoid/persistable/upsertable.rb +55 -0
- data/lib/mongoid/positional.rb +71 -0
- data/lib/mongoid/railtie.rb +156 -0
- data/lib/mongoid/railties/database.rake +97 -0
- data/lib/mongoid/railties/document.rb +12 -0
- data/lib/mongoid/relations.rb +162 -0
- data/lib/mongoid/relations/accessors.rb +299 -0
- data/lib/mongoid/relations/auto_save.rb +106 -0
- data/lib/mongoid/relations/binding.rb +218 -0
- data/lib/mongoid/relations/bindings.rb +9 -0
- data/lib/mongoid/relations/bindings/embedded/in.rb +63 -0
- data/lib/mongoid/relations/bindings/embedded/many.rb +50 -0
- data/lib/mongoid/relations/bindings/embedded/one.rb +55 -0
- data/lib/mongoid/relations/bindings/referenced/in.rb +65 -0
- data/lib/mongoid/relations/bindings/referenced/many.rb +42 -0
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +67 -0
- data/lib/mongoid/relations/bindings/referenced/one.rb +44 -0
- data/lib/mongoid/relations/builder.rb +57 -0
- data/lib/mongoid/relations/builders.rb +104 -0
- data/lib/mongoid/relations/builders/embedded/in.rb +29 -0
- data/lib/mongoid/relations/builders/embedded/many.rb +36 -0
- data/lib/mongoid/relations/builders/embedded/one.rb +30 -0
- data/lib/mongoid/relations/builders/nested_attributes/many.rb +174 -0
- data/lib/mongoid/relations/builders/nested_attributes/one.rb +126 -0
- data/lib/mongoid/relations/builders/referenced/in.rb +26 -0
- data/lib/mongoid/relations/builders/referenced/many.rb +27 -0
- data/lib/mongoid/relations/builders/referenced/many_to_many.rb +40 -0
- data/lib/mongoid/relations/builders/referenced/one.rb +26 -0
- data/lib/mongoid/relations/cascading.rb +56 -0
- data/lib/mongoid/relations/cascading/delete.rb +44 -0
- data/lib/mongoid/relations/cascading/destroy.rb +43 -0
- data/lib/mongoid/relations/cascading/nullify.rb +35 -0
- data/lib/mongoid/relations/cascading/restrict.rb +39 -0
- data/lib/mongoid/relations/constraint.rb +49 -0
- data/lib/mongoid/relations/conversions.rb +34 -0
- data/lib/mongoid/relations/counter_cache.rb +105 -0
- data/lib/mongoid/relations/cyclic.rb +107 -0
- data/lib/mongoid/relations/embedded/batchable.rb +355 -0
- data/lib/mongoid/relations/embedded/in.rb +231 -0
- data/lib/mongoid/relations/embedded/many.rb +639 -0
- data/lib/mongoid/relations/embedded/one.rb +223 -0
- data/lib/mongoid/relations/macros.rb +356 -0
- data/lib/mongoid/relations/many.rb +208 -0
- data/lib/mongoid/relations/marshalable.rb +32 -0
- data/lib/mongoid/relations/metadata.rb +1174 -0
- data/lib/mongoid/relations/nested_builder.rb +74 -0
- data/lib/mongoid/relations/one.rb +48 -0
- data/lib/mongoid/relations/options.rb +48 -0
- data/lib/mongoid/relations/polymorphic.rb +39 -0
- data/lib/mongoid/relations/proxy.rb +270 -0
- data/lib/mongoid/relations/referenced/in.rb +297 -0
- data/lib/mongoid/relations/referenced/many.rb +787 -0
- data/lib/mongoid/relations/referenced/many_to_many.rb +486 -0
- data/lib/mongoid/relations/referenced/one.rb +290 -0
- data/lib/mongoid/relations/reflections.rb +62 -0
- data/lib/mongoid/relations/synchronization.rb +169 -0
- data/lib/mongoid/relations/targets.rb +2 -0
- data/lib/mongoid/relations/targets/enumerable.rb +473 -0
- data/lib/mongoid/relations/touchable.rb +94 -0
- data/lib/mongoid/reloadable.rb +95 -0
- data/lib/mongoid/scopable.rb +379 -0
- data/lib/mongoid/selectable.rb +59 -0
- data/lib/mongoid/serializable.rb +170 -0
- data/lib/mongoid/sessions.rb +330 -0
- data/lib/mongoid/sessions/factory.rb +129 -0
- data/lib/mongoid/sessions/mongo_uri.rb +93 -0
- data/lib/mongoid/sessions/options.rb +141 -0
- data/lib/mongoid/sessions/validators.rb +2 -0
- data/lib/mongoid/sessions/validators/storage.rb +49 -0
- data/lib/mongoid/shardable.rb +65 -0
- data/lib/mongoid/state.rb +97 -0
- data/lib/mongoid/threaded.rb +383 -0
- data/lib/mongoid/threaded/lifecycle.rb +164 -0
- data/lib/mongoid/timestamps.rb +15 -0
- data/lib/mongoid/timestamps/created.rb +30 -0
- data/lib/mongoid/timestamps/created/short.rb +19 -0
- data/lib/mongoid/timestamps/short.rb +10 -0
- data/lib/mongoid/timestamps/updated.rb +39 -0
- data/lib/mongoid/timestamps/updated/short.rb +19 -0
- data/lib/mongoid/traversable.rb +192 -0
- data/lib/mongoid/unit_of_work.rb +61 -0
- data/lib/mongoid/validatable.rb +180 -0
- data/lib/mongoid/validatable/associated.rb +48 -0
- data/lib/mongoid/validatable/format.rb +20 -0
- data/lib/mongoid/validatable/length.rb +20 -0
- data/lib/mongoid/validatable/localizable.rb +30 -0
- data/lib/mongoid/validatable/macros.rb +94 -0
- data/lib/mongoid/validatable/presence.rb +86 -0
- data/lib/mongoid/validatable/queryable.rb +30 -0
- data/lib/mongoid/validatable/uniqueness.rb +330 -0
- data/lib/mongoid/version.rb +4 -0
- data/lib/rack/mongoid.rb +2 -0
- data/lib/rack/mongoid/middleware/identity_map.rb +39 -0
- data/lib/rails/generators/mongoid/config/config_generator.rb +25 -0
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +76 -0
- data/lib/rails/generators/mongoid/model/model_generator.rb +25 -0
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +19 -0
- data/lib/rails/generators/mongoid/observer/observer_generator.rb +17 -0
- data/lib/rails/generators/mongoid/observer/templates/observer.rb.tt +4 -0
- data/lib/rails/generators/mongoid_generator.rb +65 -0
- data/lib/rails/mongoid.rb +180 -0
- data/lib/support/ruby_version.rb +26 -0
- data/spec/app/models/account.rb +28 -0
- data/spec/app/models/acolyte.rb +17 -0
- data/spec/app/models/actor.rb +18 -0
- data/spec/app/models/actress.rb +2 -0
- data/spec/app/models/address.rb +77 -0
- data/spec/app/models/address_component.rb +5 -0
- data/spec/app/models/address_number.rb +6 -0
- data/spec/app/models/agency.rb +5 -0
- data/spec/app/models/agent.rb +12 -0
- data/spec/app/models/album.rb +14 -0
- data/spec/app/models/alert.rb +5 -0
- data/spec/app/models/animal.rb +25 -0
- data/spec/app/models/answer.rb +4 -0
- data/spec/app/models/appointment.rb +7 -0
- data/spec/app/models/article.rb +10 -0
- data/spec/app/models/artist.rb +66 -0
- data/spec/app/models/artwork.rb +4 -0
- data/spec/app/models/audio.rb +5 -0
- data/spec/app/models/augmentation.rb +11 -0
- data/spec/app/models/author.rb +4 -0
- data/spec/app/models/band.rb +26 -0
- data/spec/app/models/bar.rb +10 -0
- data/spec/app/models/basic.rb +6 -0
- data/spec/app/models/bed.rb +1 -0
- data/spec/app/models/big_palette.rb +2 -0
- data/spec/app/models/birthday.rb +13 -0
- data/spec/app/models/book.rb +13 -0
- data/spec/app/models/breed.rb +4 -0
- data/spec/app/models/browser.rb +6 -0
- data/spec/app/models/building.rb +5 -0
- data/spec/app/models/building_address.rb +5 -0
- data/spec/app/models/bus.rb +7 -0
- data/spec/app/models/business.rb +5 -0
- data/spec/app/models/callback_recorder.rb +25 -0
- data/spec/app/models/callback_test.rb +9 -0
- data/spec/app/models/canvas.rb +25 -0
- data/spec/app/models/car.rb +1 -0
- data/spec/app/models/cat.rb +8 -0
- data/spec/app/models/category.rb +8 -0
- data/spec/app/models/child.rb +4 -0
- data/spec/app/models/child_doc.rb +22 -0
- data/spec/app/models/church.rb +4 -0
- data/spec/app/models/circle.rb +3 -0
- data/spec/app/models/circuit.rb +4 -0
- data/spec/app/models/circus.rb +7 -0
- data/spec/app/models/code.rb +5 -0
- data/spec/app/models/comment.rb +16 -0
- data/spec/app/models/contractor.rb +5 -0
- data/spec/app/models/cookie.rb +6 -0
- data/spec/app/models/country_code.rb +8 -0
- data/spec/app/models/definition.rb +7 -0
- data/spec/app/models/description.rb +11 -0
- data/spec/app/models/dictionary.rb +10 -0
- data/spec/app/models/division.rb +10 -0
- data/spec/app/models/doctor.rb +12 -0
- data/spec/app/models/dog.rb +7 -0
- data/spec/app/models/dokument.rb +5 -0
- data/spec/app/models/dragon.rb +4 -0
- data/spec/app/models/driver.rb +7 -0
- data/spec/app/models/drug.rb +6 -0
- data/spec/app/models/dungeon.rb +4 -0
- data/spec/app/models/email.rb +6 -0
- data/spec/app/models/employer.rb +5 -0
- data/spec/app/models/entry.rb +6 -0
- data/spec/app/models/eraser.rb +1 -0
- data/spec/app/models/event.rb +22 -0
- data/spec/app/models/exhibition.rb +4 -0
- data/spec/app/models/exhibitor.rb +5 -0
- data/spec/app/models/eye.rb +9 -0
- data/spec/app/models/eye_bowl.rb +9 -0
- data/spec/app/models/face.rb +8 -0
- data/spec/app/models/favorite.rb +6 -0
- data/spec/app/models/filesystem.rb +5 -0
- data/spec/app/models/fire_hydrant.rb +6 -0
- data/spec/app/models/firefox.rb +4 -0
- data/spec/app/models/fish.rb +7 -0
- data/spec/app/models/folder.rb +7 -0
- data/spec/app/models/folder_item.rb +9 -0
- data/spec/app/models/fruits.rb +28 -0
- data/spec/app/models/game.rb +19 -0
- data/spec/app/models/ghost.rb +7 -0
- data/spec/app/models/home.rb +4 -0
- data/spec/app/models/house.rb +6 -0
- data/spec/app/models/html_writer.rb +3 -0
- data/spec/app/models/image.rb +22 -0
- data/spec/app/models/implant.rb +16 -0
- data/spec/app/models/item.rb +8 -0
- data/spec/app/models/jar.rb +7 -0
- data/spec/app/models/label.rb +40 -0
- data/spec/app/models/language.rb +5 -0
- data/spec/app/models/lat_lng.rb +15 -0
- data/spec/app/models/league.rb +11 -0
- data/spec/app/models/learner.rb +2 -0
- data/spec/app/models/line_item.rb +6 -0
- data/spec/app/models/location.rb +8 -0
- data/spec/app/models/login.rb +8 -0
- data/spec/app/models/manufacturer.rb +7 -0
- data/spec/app/models/meat.rb +4 -0
- data/spec/app/models/membership.rb +4 -0
- data/spec/app/models/mixed_drink.rb +4 -0
- data/spec/app/models/movie.rb +13 -0
- data/spec/app/models/my_hash.rb +2 -0
- data/spec/app/models/name.rb +23 -0
- data/spec/app/models/node.rb +5 -0
- data/spec/app/models/note.rb +12 -0
- data/spec/app/models/ordered_post.rb +6 -0
- data/spec/app/models/ordered_preference.rb +6 -0
- data/spec/app/models/oscar.rb +15 -0
- data/spec/app/models/override.rb +16 -0
- data/spec/app/models/ownable.rb +6 -0
- data/spec/app/models/owner.rb +6 -0
- data/spec/app/models/pack.rb +3 -0
- data/spec/app/models/page.rb +5 -0
- data/spec/app/models/page_question.rb +4 -0
- data/spec/app/models/palette.rb +7 -0
- data/spec/app/models/parent.rb +5 -0
- data/spec/app/models/parent_doc.rb +6 -0
- data/spec/app/models/passport.rb +5 -0
- data/spec/app/models/patient.rb +9 -0
- data/spec/app/models/pdf_writer.rb +3 -0
- data/spec/app/models/pencil.rb +1 -0
- data/spec/app/models/person.rb +205 -0
- data/spec/app/models/pet.rb +23 -0
- data/spec/app/models/pet_owner.rb +6 -0
- data/spec/app/models/phone.rb +11 -0
- data/spec/app/models/pizza.rb +7 -0
- data/spec/app/models/player.rb +35 -0
- data/spec/app/models/post.rb +44 -0
- data/spec/app/models/powerup.rb +11 -0
- data/spec/app/models/preference.rb +9 -0
- data/spec/app/models/princess.rb +8 -0
- data/spec/app/models/product.rb +15 -0
- data/spec/app/models/profile.rb +5 -0
- data/spec/app/models/pronunciation.rb +5 -0
- data/spec/app/models/purchase.rb +4 -0
- data/spec/app/models/question.rb +8 -0
- data/spec/app/models/quiz.rb +7 -0
- data/spec/app/models/rating.rb +8 -0
- data/spec/app/models/record.rb +46 -0
- data/spec/app/models/registry.rb +4 -0
- data/spec/app/models/role.rb +7 -0
- data/spec/app/models/root_category.rb +4 -0
- data/spec/app/models/sandwich.rb +4 -0
- data/spec/app/models/scheduler.rb +7 -0
- data/spec/app/models/seo.rb +7 -0
- data/spec/app/models/series.rb +4 -0
- data/spec/app/models/server.rb +13 -0
- data/spec/app/models/service.rb +22 -0
- data/spec/app/models/shape.rb +12 -0
- data/spec/app/models/shelf.rb +5 -0
- data/spec/app/models/shipping_container.rb +5 -0
- data/spec/app/models/shipping_pack.rb +3 -0
- data/spec/app/models/shop.rb +6 -0
- data/spec/app/models/short_agent.rb +4 -0
- data/spec/app/models/short_quiz.rb +5 -0
- data/spec/app/models/slave.rb +6 -0
- data/spec/app/models/song.rb +8 -0
- data/spec/app/models/sound.rb +5 -0
- data/spec/app/models/square.rb +4 -0
- data/spec/app/models/strategy.rb +3 -0
- data/spec/app/models/sub_item.rb +3 -0
- data/spec/app/models/subscription.rb +4 -0
- data/spec/app/models/survey.rb +5 -0
- data/spec/app/models/symptom.rb +6 -0
- data/spec/app/models/tag.rb +8 -0
- data/spec/app/models/target.rb +5 -0
- data/spec/app/models/template.rb +5 -0
- data/spec/app/models/thing.rb +9 -0
- data/spec/app/models/title.rb +3 -0
- data/spec/app/models/tool.rb +8 -0
- data/spec/app/models/topping.rb +5 -0
- data/spec/app/models/track.rb +38 -0
- data/spec/app/models/translation.rb +5 -0
- data/spec/app/models/tree.rb +9 -0
- data/spec/app/models/truck.rb +3 -0
- data/spec/app/models/user.rb +21 -0
- data/spec/app/models/user_account.rb +10 -0
- data/spec/app/models/validation_callback.rb +10 -0
- data/spec/app/models/vehicle.rb +11 -0
- data/spec/app/models/version.rb +5 -0
- data/spec/app/models/vet_visit.rb +5 -0
- data/spec/app/models/video.rb +13 -0
- data/spec/app/models/weapon.rb +11 -0
- data/spec/app/models/wiki_page.rb +14 -0
- data/spec/app/models/word.rb +15 -0
- data/spec/app/models/word_origin.rb +11 -0
- data/spec/app/models/writer.rb +11 -0
- data/spec/config/mongoid.yml +38 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +456 -0
- data/spec/mongoid/atomic/paths/embedded/many_spec.rb +118 -0
- data/spec/mongoid/atomic/paths/embedded/one_spec.rb +110 -0
- data/spec/mongoid/atomic/paths/root_spec.rb +48 -0
- data/spec/mongoid/atomic/paths_spec.rb +270 -0
- data/spec/mongoid/atomic_spec.rb +365 -0
- data/spec/mongoid/attributes/nested_spec.rb +4832 -0
- data/spec/mongoid/attributes/readonly_spec.rb +169 -0
- data/spec/mongoid/attributes_spec.rb +1412 -0
- data/spec/mongoid/changeable_spec.rb +1507 -0
- data/spec/mongoid/composable_spec.rb +24 -0
- data/spec/mongoid/config/environment_spec.rb +83 -0
- data/spec/mongoid/config/options_spec.rb +56 -0
- data/spec/mongoid/config_spec.rb +318 -0
- data/spec/mongoid/contextual/aggregable/memory_spec.rb +293 -0
- data/spec/mongoid/contextual/aggregable/mongo_spec.rb +455 -0
- data/spec/mongoid/contextual/atomic_spec.rb +529 -0
- data/spec/mongoid/contextual/find_and_modify_spec.rb +220 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +405 -0
- data/spec/mongoid/contextual/map_reduce_spec.rb +464 -0
- data/spec/mongoid/contextual/memory_spec.rb +1236 -0
- data/spec/mongoid/contextual/mongo_spec.rb +1843 -0
- data/spec/mongoid/contextual/text_search_spec.rb +207 -0
- data/spec/mongoid/copyable_spec.rb +393 -0
- data/spec/mongoid/criteria/findable_spec.rb +1189 -0
- data/spec/mongoid/criteria/inspectable_spec.rb +27 -0
- data/spec/mongoid/criteria/marshalable_spec.rb +28 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +1063 -0
- data/spec/mongoid/criteria/scopable_spec.rb +391 -0
- data/spec/mongoid/criteria_spec.rb +3821 -0
- data/spec/mongoid/document_spec.rb +1205 -0
- data/spec/mongoid/equality_spec.rb +241 -0
- data/spec/mongoid/errors/ambiguous_relationship_spec.rb +29 -0
- data/spec/mongoid/errors/callback_spec.rb +29 -0
- data/spec/mongoid/errors/delete_restriction_spec.rb +29 -0
- data/spec/mongoid/errors/document_not_found_spec.rb +104 -0
- data/spec/mongoid/errors/eager_load_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_collection_spec.rb +36 -0
- data/spec/mongoid/errors/invalid_config_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_option_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_field_spec.rb +37 -0
- data/spec/mongoid/errors/invalid_find_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_includes_spec.rb +40 -0
- data/spec/mongoid/errors/invalid_index_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_path_spec.rb +23 -0
- data/spec/mongoid/errors/invalid_scope_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_set_polymorphic_relation_spec.rb +17 -0
- data/spec/mongoid/errors/invalid_storage_options_spec.rb +29 -0
- data/spec/mongoid/errors/invalid_time_spec.rb +29 -0
- data/spec/mongoid/errors/inverse_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_relations_spec.rb +29 -0
- data/spec/mongoid/errors/mixed_session_configuration_spec.rb +29 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +48 -0
- data/spec/mongoid/errors/nested_attributes_metadata_not_found_spec.rb +29 -0
- data/spec/mongoid/errors/no_environment_spec.rb +29 -0
- data/spec/mongoid/errors/no_map_reduce_output_spec.rb +29 -0
- data/spec/mongoid/errors/no_metadata_spec.rb +23 -0
- data/spec/mongoid/errors/no_parent_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_config_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_database_spec.rb +29 -0
- data/spec/mongoid/errors/no_session_hosts_spec.rb +29 -0
- data/spec/mongoid/errors/no_sessions_config_spec.rb +29 -0
- data/spec/mongoid/errors/readonly_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/scope_overwrite_spec.rb +29 -0
- data/spec/mongoid/errors/too_many_nested_attribute_records_spec.rb +29 -0
- data/spec/mongoid/errors/unknown_attribute_spec.rb +29 -0
- data/spec/mongoid/errors/unsaved_document_spec.rb +37 -0
- data/spec/mongoid/errors/unsupported_javascript_spec.rb +29 -0
- data/spec/mongoid/errors/validations_spec.rb +45 -0
- data/spec/mongoid/extensions/array_spec.rb +638 -0
- data/spec/mongoid/extensions/big_decimal_spec.rb +104 -0
- data/spec/mongoid/extensions/binary_spec.rb +60 -0
- data/spec/mongoid/extensions/boolean_spec.rb +135 -0
- data/spec/mongoid/extensions/date_spec.rb +235 -0
- data/spec/mongoid/extensions/date_time_spec.rb +155 -0
- data/spec/mongoid/extensions/false_class_spec.rb +42 -0
- data/spec/mongoid/extensions/float_spec.rb +133 -0
- data/spec/mongoid/extensions/hash_spec.rb +333 -0
- data/spec/mongoid/extensions/integer_spec.rb +136 -0
- data/spec/mongoid/extensions/module_spec.rb +42 -0
- data/spec/mongoid/extensions/nil_class_spec.rb +11 -0
- data/spec/mongoid/extensions/object_id_spec.rb +946 -0
- data/spec/mongoid/extensions/object_spec.rb +292 -0
- data/spec/mongoid/extensions/range_spec.rb +105 -0
- data/spec/mongoid/extensions/regexp_spec.rb +47 -0
- data/spec/mongoid/extensions/set_spec.rb +33 -0
- data/spec/mongoid/extensions/string_spec.rb +357 -0
- data/spec/mongoid/extensions/symbol_spec.rb +76 -0
- data/spec/mongoid/extensions/time_spec.rb +467 -0
- data/spec/mongoid/extensions/time_with_zone_spec.rb +405 -0
- data/spec/mongoid/extensions/true_class_spec.rb +42 -0
- data/spec/mongoid/extensions_spec.rb +15 -0
- data/spec/mongoid/factory_spec.rb +185 -0
- data/spec/mongoid/fields/foreign_key_spec.rb +694 -0
- data/spec/mongoid/fields/internal/foreign_keys/array_spec.rb +184 -0
- data/spec/mongoid/fields/internal/foreign_keys/object_spec.rb +201 -0
- data/spec/mongoid/fields/localized_spec.rb +386 -0
- data/spec/mongoid/fields/standard_spec.rb +166 -0
- data/spec/mongoid/fields_spec.rb +1229 -0
- data/spec/mongoid/findable_spec.rb +342 -0
- data/spec/mongoid/identity_map_spec.rb +564 -0
- data/spec/mongoid/indexable/specification_spec.rb +87 -0
- data/spec/mongoid/indexable_spec.rb +504 -0
- data/spec/mongoid/inspectable_spec.rb +49 -0
- data/spec/mongoid/interceptable_spec.rb +1564 -0
- data/spec/mongoid/loggable_spec.rb +21 -0
- data/spec/mongoid/matchable/all_spec.rb +31 -0
- data/spec/mongoid/matchable/and_spec.rb +162 -0
- data/spec/mongoid/matchable/default_spec.rb +130 -0
- data/spec/mongoid/matchable/exists_spec.rb +57 -0
- data/spec/mongoid/matchable/gt_spec.rb +75 -0
- data/spec/mongoid/matchable/gte_spec.rb +74 -0
- data/spec/mongoid/matchable/in_spec.rb +25 -0
- data/spec/mongoid/matchable/lt_spec.rb +74 -0
- data/spec/mongoid/matchable/lte_spec.rb +74 -0
- data/spec/mongoid/matchable/ne_spec.rb +25 -0
- data/spec/mongoid/matchable/nin_spec.rb +25 -0
- data/spec/mongoid/matchable/or_spec.rb +106 -0
- data/spec/mongoid/matchable/size_spec.rb +25 -0
- data/spec/mongoid/matchable_spec.rb +532 -0
- data/spec/mongoid/persistable/creatable_spec.rb +512 -0
- data/spec/mongoid/persistable/deletable_spec.rb +205 -0
- data/spec/mongoid/persistable/destroyable_spec.rb +148 -0
- data/spec/mongoid/persistable/incrementable_spec.rb +173 -0
- data/spec/mongoid/persistable/logical_spec.rb +143 -0
- data/spec/mongoid/persistable/poppable_spec.rb +115 -0
- data/spec/mongoid/persistable/pullable_spec.rb +228 -0
- data/spec/mongoid/persistable/pushable_spec.rb +258 -0
- data/spec/mongoid/persistable/renamable_spec.rb +135 -0
- data/spec/mongoid/persistable/savable_spec.rb +432 -0
- data/spec/mongoid/persistable/settable_spec.rb +139 -0
- data/spec/mongoid/persistable/unsettable_spec.rb +155 -0
- data/spec/mongoid/persistable/updatable_spec.rb +522 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +106 -0
- data/spec/mongoid/persistable_spec.rb +206 -0
- data/spec/mongoid/positional_spec.rb +227 -0
- data/spec/mongoid/railties/document_spec.rb +24 -0
- data/spec/mongoid/relations/accessors_spec.rb +736 -0
- data/spec/mongoid/relations/auto_save_spec.rb +261 -0
- data/spec/mongoid/relations/bindings/embedded/in_spec.rb +171 -0
- data/spec/mongoid/relations/bindings/embedded/many_spec.rb +54 -0
- data/spec/mongoid/relations/bindings/embedded/one_spec.rb +77 -0
- data/spec/mongoid/relations/bindings/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/bindings/referenced/many_spec.rb +153 -0
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/bindings/referenced/one_spec.rb +131 -0
- data/spec/mongoid/relations/builders/embedded/in_spec.rb +34 -0
- data/spec/mongoid/relations/builders/embedded/many_spec.rb +132 -0
- data/spec/mongoid/relations/builders/embedded/one_spec.rb +99 -0
- data/spec/mongoid/relations/builders/nested_attributes/many_spec.rb +234 -0
- data/spec/mongoid/relations/builders/nested_attributes/one_spec.rb +250 -0
- data/spec/mongoid/relations/builders/referenced/in_spec.rb +241 -0
- data/spec/mongoid/relations/builders/referenced/many_spec.rb +137 -0
- data/spec/mongoid/relations/builders/referenced/many_to_many_spec.rb +178 -0
- data/spec/mongoid/relations/builders/referenced/one_spec.rb +124 -0
- data/spec/mongoid/relations/builders_spec.rb +226 -0
- data/spec/mongoid/relations/cascading/delete_spec.rb +101 -0
- data/spec/mongoid/relations/cascading/destroy_spec.rb +47 -0
- data/spec/mongoid/relations/cascading/nullify_spec.rb +32 -0
- data/spec/mongoid/relations/cascading/restrict_spec.rb +68 -0
- data/spec/mongoid/relations/cascading_spec.rb +355 -0
- data/spec/mongoid/relations/constraint_spec.rb +74 -0
- data/spec/mongoid/relations/conversions_spec.rb +126 -0
- data/spec/mongoid/relations/counter_cache_spec.rb +205 -0
- data/spec/mongoid/relations/cyclic_spec.rb +156 -0
- data/spec/mongoid/relations/embedded/dirty_spec.rb +65 -0
- data/spec/mongoid/relations/embedded/in_spec.rb +579 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +3781 -0
- data/spec/mongoid/relations/embedded/one_spec.rb +1014 -0
- data/spec/mongoid/relations/macros_spec.rb +613 -0
- data/spec/mongoid/relations/metadata_spec.rb +1917 -0
- data/spec/mongoid/relations/options_spec.rb +35 -0
- data/spec/mongoid/relations/polymorphic_spec.rb +128 -0
- data/spec/mongoid/relations/proxy_spec.rb +48 -0
- data/spec/mongoid/relations/referenced/in_spec.rb +1435 -0
- data/spec/mongoid/relations/referenced/many_spec.rb +3546 -0
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +3556 -0
- data/spec/mongoid/relations/referenced/one_spec.rb +1289 -0
- data/spec/mongoid/relations/reflections_spec.rb +101 -0
- data/spec/mongoid/relations/synchronization_spec.rb +449 -0
- data/spec/mongoid/relations/targets/enumerable_spec.rb +1710 -0
- data/spec/mongoid/relations/touchable_spec.rb +296 -0
- data/spec/mongoid/relations_spec.rb +188 -0
- data/spec/mongoid/reloadable_spec.rb +305 -0
- data/spec/mongoid/scopable_spec.rb +926 -0
- data/spec/mongoid/selectable_spec.rb +134 -0
- data/spec/mongoid/serializable_spec.rb +862 -0
- data/spec/mongoid/sessions/factory_spec.rb +312 -0
- data/spec/mongoid/sessions/mongo_uri_spec.rb +103 -0
- data/spec/mongoid/sessions/options_spec.rb +71 -0
- data/spec/mongoid/sessions_spec.rb +1078 -0
- data/spec/mongoid/shardable_spec.rb +61 -0
- data/spec/mongoid/state_spec.rb +102 -0
- data/spec/mongoid/threaded_spec.rb +258 -0
- data/spec/mongoid/timestamps/created/short_spec.rb +51 -0
- data/spec/mongoid/timestamps/created_spec.rb +44 -0
- data/spec/mongoid/timestamps/updated/short_spec.rb +90 -0
- data/spec/mongoid/timestamps/updated_spec.rb +86 -0
- data/spec/mongoid/timestamps_spec.rb +112 -0
- data/spec/mongoid/traversable_spec.rb +244 -0
- data/spec/mongoid/unit_of_work_spec.rb +196 -0
- data/spec/mongoid/validatable/associated_spec.rb +183 -0
- data/spec/mongoid/validatable/format_spec.rb +83 -0
- data/spec/mongoid/validatable/length_spec.rb +119 -0
- data/spec/mongoid/validatable/numericality_spec.rb +30 -0
- data/spec/mongoid/validatable/presence_spec.rb +511 -0
- data/spec/mongoid/validatable/uniqueness_spec.rb +2305 -0
- data/spec/mongoid/validatable_spec.rb +309 -0
- data/spec/mongoid_spec.rb +74 -0
- data/spec/rack/mongoid/middleware/identity_map_spec.rb +72 -0
- data/spec/rails/mongoid_spec.rb +462 -0
- data/spec/spec_helper.rb +103 -0
- metadata +1159 -0
@@ -0,0 +1,391 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Criteria::Scopable do
|
4
|
+
|
5
|
+
describe "#apply_default_scope" do
|
6
|
+
|
7
|
+
context "when the default scope has options" do
|
8
|
+
|
9
|
+
let(:scope) do
|
10
|
+
Band.skip(20)
|
11
|
+
end
|
12
|
+
|
13
|
+
before do
|
14
|
+
Band.default_scope scope
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
Band.default_scoping = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:scoped) do
|
22
|
+
Band.all.tap do |criteria|
|
23
|
+
criteria.apply_default_scope
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "merges in the options" do
|
28
|
+
expect(scoped.options).to eq({ skip: 20 })
|
29
|
+
end
|
30
|
+
|
31
|
+
it "sets scoped to true" do
|
32
|
+
expect(scoped).to be_scoped
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the default scope has selection" do
|
37
|
+
|
38
|
+
let(:scope) do
|
39
|
+
Band.where(name: "Depeche Mode")
|
40
|
+
end
|
41
|
+
|
42
|
+
before do
|
43
|
+
Band.default_scope scope
|
44
|
+
end
|
45
|
+
|
46
|
+
after do
|
47
|
+
Band.default_scoping = nil
|
48
|
+
end
|
49
|
+
|
50
|
+
let(:scoped) do
|
51
|
+
Band.all.tap do |criteria|
|
52
|
+
criteria.apply_default_scope
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
it "merges in the options" do
|
57
|
+
expect(scoped.selector).to eq({ "name" => "Depeche Mode" })
|
58
|
+
end
|
59
|
+
|
60
|
+
it "sets scoped to true" do
|
61
|
+
expect(scoped).to be_scoped
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context "when the default scope has inclusions" do
|
66
|
+
|
67
|
+
let(:scope) do
|
68
|
+
Band.includes(:records)
|
69
|
+
end
|
70
|
+
|
71
|
+
before do
|
72
|
+
Band.default_scope scope
|
73
|
+
end
|
74
|
+
|
75
|
+
after do
|
76
|
+
Band.default_scoping = nil
|
77
|
+
end
|
78
|
+
|
79
|
+
context "when merging with an empty criteria" do
|
80
|
+
|
81
|
+
let(:scoped) do
|
82
|
+
Band.all.tap do |criteria|
|
83
|
+
criteria.apply_default_scope
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
it "merges in the inclusions" do
|
88
|
+
expect(scoped.inclusions).to eq(
|
89
|
+
[ Band.relations["records"] ]
|
90
|
+
)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "sets scoped to true" do
|
94
|
+
expect(scoped).to be_scoped
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "when merging with a criteria that has inclusions" do
|
99
|
+
|
100
|
+
let(:scoped) do
|
101
|
+
Band.includes(:label).tap do |criteria|
|
102
|
+
criteria.apply_default_scope
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
it "merges in the inclusions" do
|
107
|
+
expect(scoped.inclusions).to eq(
|
108
|
+
[ Band.relations["records"], Band.relations["label"] ]
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
it "sets scoped to true" do
|
113
|
+
expect(scoped).to be_scoped
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "#remove_scoping" do
|
120
|
+
|
121
|
+
context "when the other has selection" do
|
122
|
+
|
123
|
+
let(:criteria) do
|
124
|
+
Band.where(name: "Depeche Mode")
|
125
|
+
end
|
126
|
+
|
127
|
+
before do
|
128
|
+
criteria.remove_scoping(criteria)
|
129
|
+
end
|
130
|
+
|
131
|
+
it "removes the selection" do
|
132
|
+
expect(criteria.selector).to be_empty
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
context "when the other has options" do
|
137
|
+
|
138
|
+
context "when both are options only" do
|
139
|
+
|
140
|
+
let(:criteria) do
|
141
|
+
Band.skip(10)
|
142
|
+
end
|
143
|
+
|
144
|
+
before do
|
145
|
+
criteria.remove_scoping(criteria)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "removes the options" do
|
149
|
+
expect(criteria.options).to be_empty
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
context "when the criteria is selection only with nil" do
|
154
|
+
|
155
|
+
let(:criteria) do
|
156
|
+
Band.where(name: nil)
|
157
|
+
end
|
158
|
+
|
159
|
+
before do
|
160
|
+
criteria.remove_scoping(Band.asc(:_id))
|
161
|
+
end
|
162
|
+
|
163
|
+
it "removes the options" do
|
164
|
+
expect(criteria.options).to be_empty
|
165
|
+
end
|
166
|
+
|
167
|
+
it "does not remove the selector" do
|
168
|
+
expect(criteria.selector).to eq({ "name" => nil })
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
context "when the other has inclusions" do
|
174
|
+
|
175
|
+
let(:criteria) do
|
176
|
+
Band.includes(:records, :label)
|
177
|
+
end
|
178
|
+
|
179
|
+
let(:other) do
|
180
|
+
Band.includes(:label)
|
181
|
+
end
|
182
|
+
|
183
|
+
before do
|
184
|
+
criteria.remove_scoping(other)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "removes the matching inclusions" do
|
188
|
+
expect(criteria.inclusions).to eq([ Band.relations["records"] ])
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#scoped" do
|
194
|
+
|
195
|
+
let(:empty) do
|
196
|
+
Mongoid::Criteria.new(Band)
|
197
|
+
end
|
198
|
+
|
199
|
+
context "when no options are provided" do
|
200
|
+
|
201
|
+
let(:scoped) do
|
202
|
+
empty.scoped
|
203
|
+
end
|
204
|
+
|
205
|
+
it "returns a criteria" do
|
206
|
+
expect(scoped).to be_a(Mongoid::Criteria)
|
207
|
+
end
|
208
|
+
|
209
|
+
it "contains an empty selector" do
|
210
|
+
expect(scoped.selector).to be_empty
|
211
|
+
end
|
212
|
+
|
213
|
+
it "contains empty options" do
|
214
|
+
expect(scoped.options).to be_empty
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context "when options are provided" do
|
219
|
+
|
220
|
+
let(:scoped) do
|
221
|
+
empty.scoped(skip: 10, limit: 10)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "returns a criteria" do
|
225
|
+
expect(scoped).to be_a(Mongoid::Criteria)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "contains an empty selector" do
|
229
|
+
expect(scoped.selector).to be_empty
|
230
|
+
end
|
231
|
+
|
232
|
+
it "contains the options" do
|
233
|
+
expect(scoped.options).to eq({ skip: 10, limit: 10 })
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
context "when a default scope exists" do
|
238
|
+
|
239
|
+
let(:criteria) do
|
240
|
+
Band.where(name: "Depeche Mode")
|
241
|
+
end
|
242
|
+
|
243
|
+
before do
|
244
|
+
Band.default_scope criteria
|
245
|
+
end
|
246
|
+
|
247
|
+
after do
|
248
|
+
Band.default_scoping = nil
|
249
|
+
end
|
250
|
+
|
251
|
+
let(:scoped) do
|
252
|
+
empty.scoped
|
253
|
+
end
|
254
|
+
|
255
|
+
it "allows the default scope to be added" do
|
256
|
+
expect(scoped.selector).to eq({ "name" => "Depeche Mode" })
|
257
|
+
end
|
258
|
+
|
259
|
+
it "flags as scoped" do
|
260
|
+
expect(scoped).to be_scoped
|
261
|
+
end
|
262
|
+
|
263
|
+
context "when chained after an unscoped criteria" do
|
264
|
+
|
265
|
+
let(:scoped) do
|
266
|
+
empty.unscoped.scoped
|
267
|
+
end
|
268
|
+
|
269
|
+
it "reapplies the default scope" do
|
270
|
+
expect(scoped.selector).to eq({ "name" => "Depeche Mode" })
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
describe "#scoping_options" do
|
277
|
+
|
278
|
+
let(:criteria) do
|
279
|
+
Band.all
|
280
|
+
end
|
281
|
+
|
282
|
+
before do
|
283
|
+
criteria.scoping_options = true, false
|
284
|
+
end
|
285
|
+
|
286
|
+
it "returns the scoping options" do
|
287
|
+
expect(criteria.scoping_options).to eq([ true, false ])
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
describe "#scoping_options=" do
|
292
|
+
|
293
|
+
let(:criteria) do
|
294
|
+
Band.all
|
295
|
+
end
|
296
|
+
|
297
|
+
before do
|
298
|
+
criteria.scoping_options = true, true
|
299
|
+
end
|
300
|
+
|
301
|
+
it "sets the scoped flag" do
|
302
|
+
expect(criteria).to be_scoped
|
303
|
+
end
|
304
|
+
|
305
|
+
it "sets the unscoped flag" do
|
306
|
+
expect(criteria).to be_unscoped
|
307
|
+
end
|
308
|
+
end
|
309
|
+
|
310
|
+
describe ".unscoped" do
|
311
|
+
|
312
|
+
let(:empty) do
|
313
|
+
Mongoid::Criteria.new(Band)
|
314
|
+
end
|
315
|
+
|
316
|
+
let(:criteria) do
|
317
|
+
Band.where(name: "Depeche Mode")
|
318
|
+
end
|
319
|
+
|
320
|
+
before do
|
321
|
+
Band.default_scope criteria
|
322
|
+
end
|
323
|
+
|
324
|
+
after do
|
325
|
+
Band.default_scoping = nil
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when called directly" do
|
329
|
+
|
330
|
+
let(:unscoped) do
|
331
|
+
empty.unscoped
|
332
|
+
end
|
333
|
+
|
334
|
+
it "removes the default scope from the criteria" do
|
335
|
+
expect(unscoped.selector).to be_empty
|
336
|
+
end
|
337
|
+
|
338
|
+
context "when chained after a scoped criteria" do
|
339
|
+
|
340
|
+
let(:unscoped) do
|
341
|
+
empty.scoped.unscoped
|
342
|
+
end
|
343
|
+
|
344
|
+
it "removes all scoping" do
|
345
|
+
expect(unscoped.selector).to be_empty
|
346
|
+
end
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
context "when used with a block" do
|
351
|
+
|
352
|
+
context "when a criteria is called in the block" do
|
353
|
+
|
354
|
+
it "does not allow default scoping to be added in the block" do
|
355
|
+
Band.unscoped do
|
356
|
+
expect(empty.skip(10).selector).to be_empty
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
context "when a call is made to scoped in the block" do
|
362
|
+
|
363
|
+
it "does not allow default scoping to be added in the block" do
|
364
|
+
Band.unscoped do
|
365
|
+
expect(empty.scoped.selector).to be_empty
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
|
370
|
+
context "when a named scope is called in the block" do
|
371
|
+
|
372
|
+
before do
|
373
|
+
Band.scope(:skipped, Band.skip(10))
|
374
|
+
end
|
375
|
+
|
376
|
+
after do
|
377
|
+
class << Band
|
378
|
+
undef_method :skipped
|
379
|
+
end
|
380
|
+
Band._declared_scopes.clear
|
381
|
+
end
|
382
|
+
|
383
|
+
it "does not allow the default scope to be applied" do
|
384
|
+
Band.unscoped do
|
385
|
+
expect(empty.skipped.selector).to be_empty
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
end
|
391
|
+
end
|
@@ -0,0 +1,3821 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Mongoid::Criteria do
|
4
|
+
|
5
|
+
describe "#==" do
|
6
|
+
|
7
|
+
let(:criteria) do
|
8
|
+
Band.where(name: "Depeche Mode")
|
9
|
+
end
|
10
|
+
|
11
|
+
context "when the other is a criteria" do
|
12
|
+
|
13
|
+
context "when the criteria are the same" do
|
14
|
+
|
15
|
+
let(:other) do
|
16
|
+
Band.where(name: "Depeche Mode")
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns true" do
|
20
|
+
expect(criteria).to eq(other)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "when the criteria differ" do
|
25
|
+
|
26
|
+
let(:other) do
|
27
|
+
Band.where(name: "Tool")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns false" do
|
31
|
+
expect(criteria).to_not eq(other)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "when the other is an enumerable" do
|
37
|
+
|
38
|
+
context "when the entries are the same" do
|
39
|
+
|
40
|
+
let!(:band) do
|
41
|
+
Band.create(name: "Depeche Mode")
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:other) do
|
45
|
+
[ band ]
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns true" do
|
49
|
+
expect(criteria).to eq(other)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
context "when the entries are not the same" do
|
54
|
+
|
55
|
+
let!(:band) do
|
56
|
+
Band.create(name: "Depeche Mode")
|
57
|
+
end
|
58
|
+
|
59
|
+
let!(:other_band) do
|
60
|
+
Band.create(name: "Tool")
|
61
|
+
end
|
62
|
+
|
63
|
+
let(:other) do
|
64
|
+
[ other_band ]
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns false" do
|
68
|
+
expect(criteria).to_not eq(other)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when the other is neither a criteria or enumerable" do
|
74
|
+
|
75
|
+
it "returns false" do
|
76
|
+
expect(criteria).to_not eq("test")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "#===" do
|
82
|
+
|
83
|
+
context "when the other is a criteria" do
|
84
|
+
|
85
|
+
let(:other) do
|
86
|
+
Band.where(name: "Depeche Mode")
|
87
|
+
end
|
88
|
+
|
89
|
+
it "returns true" do
|
90
|
+
expect(described_class === other).to be_true
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "when the other is not a criteria" do
|
95
|
+
|
96
|
+
it "returns false" do
|
97
|
+
expect(described_class === []).to be_false
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe "#asc" do
|
103
|
+
|
104
|
+
let(:person) do
|
105
|
+
Person.create
|
106
|
+
end
|
107
|
+
|
108
|
+
context "when the documents are embedded" do
|
109
|
+
|
110
|
+
let!(:hobrecht) do
|
111
|
+
person.addresses.create(street: "hobrecht", name: "hobrecht")
|
112
|
+
end
|
113
|
+
|
114
|
+
let!(:friedel) do
|
115
|
+
person.addresses.create(street: "friedel", name: "friedel")
|
116
|
+
end
|
117
|
+
|
118
|
+
let!(:pfluger) do
|
119
|
+
person.addresses.create(street: "pfluger", name: "pfluger")
|
120
|
+
end
|
121
|
+
|
122
|
+
let(:criteria) do
|
123
|
+
person.addresses.asc(:name)
|
124
|
+
end
|
125
|
+
|
126
|
+
it "returns the sorted documents" do
|
127
|
+
expect(criteria).to eq([ friedel, hobrecht, pfluger ])
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#batch_size" do
|
133
|
+
|
134
|
+
let(:person) do
|
135
|
+
Person.create
|
136
|
+
end
|
137
|
+
|
138
|
+
let(:criteria) do
|
139
|
+
Person.batch_size(1000)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "adds the batch size option" do
|
143
|
+
expect(criteria.options[:batch_size]).to eq(1000)
|
144
|
+
end
|
145
|
+
|
146
|
+
it "returns the correct documents" do
|
147
|
+
expect(criteria).to eq([ person ])
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "#aggregates" do
|
152
|
+
|
153
|
+
context "when provided a single field" do
|
154
|
+
|
155
|
+
let!(:depeche) do
|
156
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
157
|
+
end
|
158
|
+
|
159
|
+
let!(:tool) do
|
160
|
+
Band.create(name: "Tool", likes: 500)
|
161
|
+
end
|
162
|
+
|
163
|
+
let(:criteria) do
|
164
|
+
Band.all
|
165
|
+
end
|
166
|
+
|
167
|
+
let(:aggregates) do
|
168
|
+
criteria.aggregates(:likes)
|
169
|
+
end
|
170
|
+
|
171
|
+
it "returns an avg" do
|
172
|
+
expect(aggregates["avg"]).to eq(750)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "returns a count" do
|
176
|
+
expect(aggregates["count"]).to eq(2)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "returns a max" do
|
180
|
+
expect(aggregates["max"]).to eq(1000)
|
181
|
+
end
|
182
|
+
|
183
|
+
it "returns a min" do
|
184
|
+
expect(aggregates["min"]).to eq(500)
|
185
|
+
end
|
186
|
+
|
187
|
+
it "returns a sum" do
|
188
|
+
expect(aggregates["sum"]).to eq(1500)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
describe "#avg" do
|
194
|
+
|
195
|
+
context "when provided a single field" do
|
196
|
+
|
197
|
+
let!(:depeche) do
|
198
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
199
|
+
end
|
200
|
+
|
201
|
+
let!(:tool) do
|
202
|
+
Band.create(name: "Tool", likes: 500)
|
203
|
+
end
|
204
|
+
|
205
|
+
let(:criteria) do
|
206
|
+
Band.all
|
207
|
+
end
|
208
|
+
|
209
|
+
let(:avg) do
|
210
|
+
criteria.avg(:likes)
|
211
|
+
end
|
212
|
+
|
213
|
+
it "returns the avg of the provided field" do
|
214
|
+
expect(avg).to eq(750)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
[ :all, :all_in ].each do |method|
|
220
|
+
|
221
|
+
describe "\##{method}" do
|
222
|
+
|
223
|
+
let!(:match) do
|
224
|
+
Band.create(genres: [ "electro", "dub" ])
|
225
|
+
end
|
226
|
+
|
227
|
+
let!(:non_match) do
|
228
|
+
Band.create(genres: [ "house" ])
|
229
|
+
end
|
230
|
+
|
231
|
+
let(:criteria) do
|
232
|
+
Band.send(method, genres: [ "electro", "dub" ])
|
233
|
+
end
|
234
|
+
|
235
|
+
it "returns the matching documents" do
|
236
|
+
expect(criteria).to eq([ match ])
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
|
241
|
+
[ :and, :all_of ].each do |method|
|
242
|
+
|
243
|
+
describe "\##{method}" do
|
244
|
+
|
245
|
+
let!(:match) do
|
246
|
+
Band.create(name: "Depeche Mode", genres: [ "electro" ])
|
247
|
+
end
|
248
|
+
|
249
|
+
let!(:non_match) do
|
250
|
+
Band.create(genres: [ "house" ])
|
251
|
+
end
|
252
|
+
|
253
|
+
let(:criteria) do
|
254
|
+
Band.send(method, { genres: "electro" }, { name: "Depeche Mode" })
|
255
|
+
end
|
256
|
+
|
257
|
+
it "returns the matching documents" do
|
258
|
+
expect(criteria).to eq([ match ])
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "#as_json" do
|
264
|
+
|
265
|
+
let!(:band) do
|
266
|
+
Band.create(name: "Depeche Mode")
|
267
|
+
end
|
268
|
+
|
269
|
+
let(:criteria) do
|
270
|
+
Band.where(name: "Depeche Mode")
|
271
|
+
end
|
272
|
+
|
273
|
+
it "returns the criteria as a json hash" do
|
274
|
+
expect(criteria.as_json).to eq([ band.serializable_hash ])
|
275
|
+
end
|
276
|
+
end
|
277
|
+
|
278
|
+
describe "#between" do
|
279
|
+
|
280
|
+
let!(:match) do
|
281
|
+
Band.create(member_count: 3)
|
282
|
+
end
|
283
|
+
|
284
|
+
let!(:non_match) do
|
285
|
+
Band.create(member_count: 10)
|
286
|
+
end
|
287
|
+
|
288
|
+
let(:criteria) do
|
289
|
+
Band.between(member_count: 1..5)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "returns the matching documents" do
|
293
|
+
expect(criteria).to eq([ match ])
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
[ :build, :new ].each do |method|
|
298
|
+
|
299
|
+
describe "##{method}" do
|
300
|
+
|
301
|
+
let(:criteria) do
|
302
|
+
Band.where(name: "Depeche Mode")
|
303
|
+
end
|
304
|
+
|
305
|
+
context "when provided valid attributes" do
|
306
|
+
|
307
|
+
let(:band) do
|
308
|
+
criteria.send(method, genres: [ "electro" ])
|
309
|
+
end
|
310
|
+
|
311
|
+
it "returns the new document" do
|
312
|
+
expect(band).to be_new_record
|
313
|
+
end
|
314
|
+
|
315
|
+
it "sets the criteria attributes" do
|
316
|
+
expect(band.name).to eq("Depeche Mode")
|
317
|
+
end
|
318
|
+
|
319
|
+
it "sets the attributes passed to build" do
|
320
|
+
expect(band.genres).to eq([ "electro" ])
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
context "when provided a block" do
|
325
|
+
context "when provided valid attributes" do
|
326
|
+
let(:band) do
|
327
|
+
criteria.send(method) do |c|
|
328
|
+
c.genres = [ "electro" ]
|
329
|
+
end
|
330
|
+
end
|
331
|
+
|
332
|
+
it "returns the new document" do
|
333
|
+
expect(band).to be_new_record
|
334
|
+
end
|
335
|
+
|
336
|
+
it "sets the criteria attributes" do
|
337
|
+
expect(band.name).to eq("Depeche Mode")
|
338
|
+
end
|
339
|
+
|
340
|
+
it "sets the attributes passed to build" do
|
341
|
+
expect(band.genres).to eq([ "electro" ])
|
342
|
+
end
|
343
|
+
end
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
describe "#cache" do
|
349
|
+
|
350
|
+
let!(:person) do
|
351
|
+
Person.create
|
352
|
+
end
|
353
|
+
|
354
|
+
context "when no eager loading is involved" do
|
355
|
+
|
356
|
+
let(:criteria) do
|
357
|
+
Person.all.cache
|
358
|
+
end
|
359
|
+
|
360
|
+
before do
|
361
|
+
criteria.each {}
|
362
|
+
end
|
363
|
+
|
364
|
+
it "does not hit the database after first iteration" do
|
365
|
+
criteria.context.query.should_receive(:each).never
|
366
|
+
criteria.each do |doc|
|
367
|
+
expect(doc).to eq(person)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
|
372
|
+
context "when the criteria is eager loading" do
|
373
|
+
|
374
|
+
let(:criteria) do
|
375
|
+
Person.includes(:posts).cache
|
376
|
+
end
|
377
|
+
|
378
|
+
before do
|
379
|
+
criteria.each {}
|
380
|
+
end
|
381
|
+
|
382
|
+
it "does not hit the database after first iteration" do
|
383
|
+
criteria.context.query.should_receive(:each).never
|
384
|
+
criteria.each do |doc|
|
385
|
+
expect(doc).to eq(person)
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
[ :clone, :dup ].each do |method|
|
392
|
+
|
393
|
+
describe "\##{method}" do
|
394
|
+
|
395
|
+
let(:band) do
|
396
|
+
Band.new
|
397
|
+
end
|
398
|
+
|
399
|
+
let(:criteria) do
|
400
|
+
Band.where(name: "Depeche Mode").asc(:name).includes(:records)
|
401
|
+
end
|
402
|
+
|
403
|
+
before do
|
404
|
+
criteria.documents = [ band ]
|
405
|
+
criteria.context
|
406
|
+
end
|
407
|
+
|
408
|
+
let(:clone) do
|
409
|
+
criteria.send(method)
|
410
|
+
end
|
411
|
+
|
412
|
+
it "contains an equal selector" do
|
413
|
+
expect(clone.selector).to eq({ "name" => "Depeche Mode" })
|
414
|
+
end
|
415
|
+
|
416
|
+
it "clones the selector" do
|
417
|
+
expect(clone.selector).to_not equal(criteria.selector)
|
418
|
+
end
|
419
|
+
|
420
|
+
it "contains equal options" do
|
421
|
+
expect(clone.options).to eq({ sort: { "name" => 1 }})
|
422
|
+
end
|
423
|
+
|
424
|
+
it "clones the options" do
|
425
|
+
expect(clone.options).to_not equal(criteria.options)
|
426
|
+
end
|
427
|
+
|
428
|
+
it "contains equal inclusions" do
|
429
|
+
expect(clone.inclusions).to eq([ Band.relations["records"] ])
|
430
|
+
end
|
431
|
+
|
432
|
+
it "clones the inclusions" do
|
433
|
+
expect(clone.inclusions).to_not equal(criteria.inclusions)
|
434
|
+
end
|
435
|
+
|
436
|
+
it "contains equal documents" do
|
437
|
+
expect(clone.documents).to eq([ band ])
|
438
|
+
end
|
439
|
+
|
440
|
+
it "clones the documents" do
|
441
|
+
expect(clone.documents).to_not equal(criteria.documents)
|
442
|
+
end
|
443
|
+
|
444
|
+
it "contains equal scoping options" do
|
445
|
+
expect(clone.scoping_options).to eq([ nil, nil ])
|
446
|
+
end
|
447
|
+
|
448
|
+
it "clones the scoping options" do
|
449
|
+
expect(clone.scoping_options).to_not equal(criteria.scoping_options)
|
450
|
+
end
|
451
|
+
|
452
|
+
it "sets the context to nil" do
|
453
|
+
expect(clone.instance_variable_get(:@context)).to be_nil
|
454
|
+
end
|
455
|
+
end
|
456
|
+
end
|
457
|
+
|
458
|
+
describe "#cache" do
|
459
|
+
|
460
|
+
let(:criteria) do
|
461
|
+
Band.where(name: "Depeche Mode")
|
462
|
+
end
|
463
|
+
|
464
|
+
it "sets the cache option to true" do
|
465
|
+
expect(criteria.cache).to be_cached
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
describe "#context" do
|
470
|
+
|
471
|
+
context "when the model is embedded" do
|
472
|
+
|
473
|
+
let(:criteria) do
|
474
|
+
described_class.new(Record) do |criteria|
|
475
|
+
criteria.embedded = true
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
it "returns the embedded context" do
|
480
|
+
expect(criteria.context).to be_a(Mongoid::Contextual::Memory)
|
481
|
+
end
|
482
|
+
end
|
483
|
+
|
484
|
+
context "when the model is not embedded" do
|
485
|
+
|
486
|
+
let(:criteria) do
|
487
|
+
described_class.new(Band)
|
488
|
+
end
|
489
|
+
|
490
|
+
it "returns the mongo context" do
|
491
|
+
expect(criteria.context).to be_a(Mongoid::Contextual::Mongo)
|
492
|
+
end
|
493
|
+
end
|
494
|
+
end
|
495
|
+
|
496
|
+
describe "#delete" do
|
497
|
+
|
498
|
+
let(:depeche) do
|
499
|
+
Band.create(name: "Depeche Mode")
|
500
|
+
end
|
501
|
+
|
502
|
+
let(:tool) do
|
503
|
+
Band.create(name: "Tool")
|
504
|
+
end
|
505
|
+
|
506
|
+
context "when no selector is provided" do
|
507
|
+
|
508
|
+
before do
|
509
|
+
Band.all.delete
|
510
|
+
end
|
511
|
+
|
512
|
+
it "deletes all the documents from the database" do
|
513
|
+
expect(Band.count).to eq(0)
|
514
|
+
end
|
515
|
+
end
|
516
|
+
end
|
517
|
+
|
518
|
+
describe "#documents" do
|
519
|
+
|
520
|
+
let(:band) do
|
521
|
+
Band.new
|
522
|
+
end
|
523
|
+
|
524
|
+
let(:criteria) do
|
525
|
+
described_class.new(Band) do |criteria|
|
526
|
+
criteria.documents = [ band ]
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
it "returns the documents" do
|
531
|
+
expect(criteria.documents).to eq([ band ])
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
describe "#documents=" do
|
536
|
+
|
537
|
+
let(:band) do
|
538
|
+
Band.new
|
539
|
+
end
|
540
|
+
|
541
|
+
let(:criteria) do
|
542
|
+
described_class.new(Band)
|
543
|
+
end
|
544
|
+
|
545
|
+
before do
|
546
|
+
criteria.documents = [ band ]
|
547
|
+
end
|
548
|
+
|
549
|
+
it "sets the documents" do
|
550
|
+
expect(criteria.documents).to eq([ band ])
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
describe "#each" do
|
555
|
+
|
556
|
+
let!(:band) do
|
557
|
+
Band.create(name: "Depeche Mode")
|
558
|
+
end
|
559
|
+
|
560
|
+
context "when provided a block" do
|
561
|
+
|
562
|
+
let(:criteria) do
|
563
|
+
Band.where(name: "Depeche Mode")
|
564
|
+
end
|
565
|
+
|
566
|
+
it "iterates over the matching documents" do
|
567
|
+
criteria.each do |doc|
|
568
|
+
expect(doc).to eq(band)
|
569
|
+
end
|
570
|
+
end
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
describe "#elem_match" do
|
575
|
+
|
576
|
+
let!(:match) do
|
577
|
+
Band.create(name: "Depeche Mode").tap do |band|
|
578
|
+
band.records.create(name: "101")
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
let!(:non_match) do
|
583
|
+
Band.create(genres: [ "house" ])
|
584
|
+
end
|
585
|
+
|
586
|
+
let(:criteria) do
|
587
|
+
Band.elem_match(records: { name: "101" })
|
588
|
+
end
|
589
|
+
|
590
|
+
it "returns the matching documents" do
|
591
|
+
expect(criteria).to eq([ match ])
|
592
|
+
end
|
593
|
+
end
|
594
|
+
|
595
|
+
describe "#embedded?" do
|
596
|
+
|
597
|
+
let(:person) do
|
598
|
+
Person.new
|
599
|
+
end
|
600
|
+
|
601
|
+
context "when the criteria is embedded" do
|
602
|
+
|
603
|
+
let(:criteria) do
|
604
|
+
person.addresses.where(street: "hobrecht")
|
605
|
+
end
|
606
|
+
|
607
|
+
it "returns true" do
|
608
|
+
expect(criteria).to be_embedded
|
609
|
+
end
|
610
|
+
end
|
611
|
+
|
612
|
+
context "when the criteria is not embedded" do
|
613
|
+
|
614
|
+
let(:criteria) do
|
615
|
+
Person.where(active: true)
|
616
|
+
end
|
617
|
+
|
618
|
+
it "returns false" do
|
619
|
+
expect(criteria).to_not be_embedded
|
620
|
+
end
|
621
|
+
end
|
622
|
+
end
|
623
|
+
|
624
|
+
describe "#empty?" do
|
625
|
+
|
626
|
+
context "when matching documents exist" do
|
627
|
+
|
628
|
+
let!(:match) do
|
629
|
+
Band.create(name: "Depeche Mode")
|
630
|
+
end
|
631
|
+
|
632
|
+
let(:criteria) do
|
633
|
+
Band.where(name: "Depeche Mode")
|
634
|
+
end
|
635
|
+
|
636
|
+
it "returns false" do
|
637
|
+
expect(criteria).to_not be_empty
|
638
|
+
end
|
639
|
+
end
|
640
|
+
|
641
|
+
context "when no matching documents exist" do
|
642
|
+
|
643
|
+
let!(:nonmatch) do
|
644
|
+
Band.create(name: "New Order")
|
645
|
+
end
|
646
|
+
|
647
|
+
let(:criteria) do
|
648
|
+
Band.where(name: "Depeche Mode")
|
649
|
+
end
|
650
|
+
|
651
|
+
it "returns true" do
|
652
|
+
expect(criteria).to be_empty
|
653
|
+
end
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
describe "#exists" do
|
658
|
+
|
659
|
+
let!(:match) do
|
660
|
+
Band.create(name: "Depeche Mode")
|
661
|
+
end
|
662
|
+
|
663
|
+
let!(:non_match) do
|
664
|
+
Band.create
|
665
|
+
end
|
666
|
+
|
667
|
+
let(:criteria) do
|
668
|
+
Band.exists(name: true)
|
669
|
+
end
|
670
|
+
|
671
|
+
it "returns the matching documents" do
|
672
|
+
expect(criteria).to eq([ match ])
|
673
|
+
end
|
674
|
+
end
|
675
|
+
|
676
|
+
describe "#exists?" do
|
677
|
+
|
678
|
+
context "when matching documents exist" do
|
679
|
+
|
680
|
+
let!(:match) do
|
681
|
+
Band.create(name: "Depeche Mode")
|
682
|
+
end
|
683
|
+
|
684
|
+
let(:criteria) do
|
685
|
+
Band.where(name: "Depeche Mode")
|
686
|
+
end
|
687
|
+
|
688
|
+
it "returns true" do
|
689
|
+
expect(criteria.exists?).to be_true
|
690
|
+
end
|
691
|
+
end
|
692
|
+
|
693
|
+
context "when no matching documents exist" do
|
694
|
+
|
695
|
+
let(:criteria) do
|
696
|
+
Band.where(name: "Depeche Mode")
|
697
|
+
end
|
698
|
+
|
699
|
+
it "returns false" do
|
700
|
+
expect(criteria.exists?).to be_false
|
701
|
+
end
|
702
|
+
end
|
703
|
+
end
|
704
|
+
|
705
|
+
describe "#explain" do
|
706
|
+
|
707
|
+
let(:criteria) do
|
708
|
+
Band.where(name: "Depeche Mode")
|
709
|
+
end
|
710
|
+
|
711
|
+
it "returns the criteria explain path" do
|
712
|
+
expect(criteria.explain["cursor"]).to eq("BasicCursor")
|
713
|
+
end
|
714
|
+
end
|
715
|
+
|
716
|
+
describe "#extract_id" do
|
717
|
+
|
718
|
+
let(:id) do
|
719
|
+
Moped::BSON::ObjectId.new
|
720
|
+
end
|
721
|
+
|
722
|
+
context "when an id exists" do
|
723
|
+
|
724
|
+
let(:criteria) do
|
725
|
+
described_class.new(Band) do |criteria|
|
726
|
+
criteria.selector[:id] = id
|
727
|
+
end
|
728
|
+
end
|
729
|
+
|
730
|
+
it "returns the id" do
|
731
|
+
expect(criteria.extract_id).to eq(id)
|
732
|
+
end
|
733
|
+
end
|
734
|
+
|
735
|
+
context "when an _id exists" do
|
736
|
+
|
737
|
+
let(:criteria) do
|
738
|
+
described_class.new(Band) do |criteria|
|
739
|
+
criteria.selector[:_id] = id
|
740
|
+
end
|
741
|
+
end
|
742
|
+
|
743
|
+
it "returns the _id" do
|
744
|
+
expect(criteria.extract_id).to eq(id)
|
745
|
+
end
|
746
|
+
end
|
747
|
+
end
|
748
|
+
|
749
|
+
describe "#field_list" do
|
750
|
+
|
751
|
+
let(:criteria) do
|
752
|
+
Band.only(:name)
|
753
|
+
end
|
754
|
+
|
755
|
+
it "returns the fields minus type" do
|
756
|
+
expect(criteria.field_list).to eq([ "name" ])
|
757
|
+
end
|
758
|
+
end
|
759
|
+
|
760
|
+
describe "#find_and_modify" do
|
761
|
+
|
762
|
+
let!(:depeche) do
|
763
|
+
Band.create(name: "Depeche Mode")
|
764
|
+
end
|
765
|
+
|
766
|
+
let!(:tool) do
|
767
|
+
Band.create(name: "Tool")
|
768
|
+
end
|
769
|
+
|
770
|
+
context "when the selector matches" do
|
771
|
+
|
772
|
+
context "when the identity map is enabled" do
|
773
|
+
|
774
|
+
before(:all) do
|
775
|
+
Mongoid.identity_map_enabled = true
|
776
|
+
end
|
777
|
+
|
778
|
+
after(:all) do
|
779
|
+
Mongoid.identity_map_enabled = false
|
780
|
+
end
|
781
|
+
|
782
|
+
context "when returning the updated document" do
|
783
|
+
|
784
|
+
let(:criteria) do
|
785
|
+
Band.where(name: "Depeche Mode")
|
786
|
+
end
|
787
|
+
|
788
|
+
let(:result) do
|
789
|
+
criteria.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
|
790
|
+
end
|
791
|
+
|
792
|
+
it "returns the first matching document" do
|
793
|
+
expect(result).to eq(depeche)
|
794
|
+
end
|
795
|
+
|
796
|
+
it "updates the document in the identity map" do
|
797
|
+
expect(Mongoid::IdentityMap.get(Band, result.id).likes).to eq(1)
|
798
|
+
end
|
799
|
+
end
|
800
|
+
|
801
|
+
context "when not returning the updated document" do
|
802
|
+
|
803
|
+
let(:criteria) do
|
804
|
+
Band.where(name: "Depeche Mode")
|
805
|
+
end
|
806
|
+
|
807
|
+
let!(:result) do
|
808
|
+
criteria.find_and_modify("$inc" => { likes: 1 })
|
809
|
+
end
|
810
|
+
|
811
|
+
before do
|
812
|
+
depeche.reload
|
813
|
+
end
|
814
|
+
|
815
|
+
it "returns the first matching document" do
|
816
|
+
expect(result).to eq(depeche)
|
817
|
+
end
|
818
|
+
|
819
|
+
it "updates the document in the identity map" do
|
820
|
+
expect(Mongoid::IdentityMap.get(Band, depeche.id).likes).to eq(1)
|
821
|
+
end
|
822
|
+
end
|
823
|
+
end
|
824
|
+
|
825
|
+
context "when not providing options" do
|
826
|
+
|
827
|
+
let(:criteria) do
|
828
|
+
Band.where(name: "Depeche Mode")
|
829
|
+
end
|
830
|
+
|
831
|
+
let!(:result) do
|
832
|
+
criteria.find_and_modify("$inc" => { likes: 1 })
|
833
|
+
end
|
834
|
+
|
835
|
+
it "returns the first matching document" do
|
836
|
+
expect(result).to eq(depeche)
|
837
|
+
end
|
838
|
+
|
839
|
+
it "updates the document in the database" do
|
840
|
+
expect(depeche.reload.likes).to eq(1)
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
context "when sorting" do
|
845
|
+
|
846
|
+
let(:criteria) do
|
847
|
+
Band.desc(:name)
|
848
|
+
end
|
849
|
+
|
850
|
+
let!(:result) do
|
851
|
+
criteria.find_and_modify("$inc" => { likes: 1 })
|
852
|
+
end
|
853
|
+
|
854
|
+
it "returns the first matching document" do
|
855
|
+
expect(result).to eq(tool)
|
856
|
+
end
|
857
|
+
|
858
|
+
it "updates the document in the database" do
|
859
|
+
expect(tool.reload.likes).to eq(1)
|
860
|
+
end
|
861
|
+
end
|
862
|
+
|
863
|
+
context "when limiting fields" do
|
864
|
+
|
865
|
+
let(:criteria) do
|
866
|
+
Band.only(:_id)
|
867
|
+
end
|
868
|
+
|
869
|
+
let!(:result) do
|
870
|
+
criteria.find_and_modify("$inc" => { likes: 1 })
|
871
|
+
end
|
872
|
+
|
873
|
+
it "returns the first matching document" do
|
874
|
+
expect(result).to eq(depeche)
|
875
|
+
end
|
876
|
+
|
877
|
+
it "limits the returned fields" do
|
878
|
+
expect(result.name).to be_nil
|
879
|
+
end
|
880
|
+
|
881
|
+
it "updates the document in the database" do
|
882
|
+
expect(depeche.reload.likes).to eq(1)
|
883
|
+
end
|
884
|
+
end
|
885
|
+
|
886
|
+
context "when returning new" do
|
887
|
+
|
888
|
+
let(:criteria) do
|
889
|
+
Band.where(name: "Depeche Mode")
|
890
|
+
end
|
891
|
+
|
892
|
+
let!(:result) do
|
893
|
+
criteria.find_and_modify({ "$inc" => { likes: 1 }}, new: true)
|
894
|
+
end
|
895
|
+
|
896
|
+
it "returns the first matching document" do
|
897
|
+
expect(result).to eq(depeche)
|
898
|
+
end
|
899
|
+
|
900
|
+
it "returns the updated document" do
|
901
|
+
expect(result.likes).to eq(1)
|
902
|
+
end
|
903
|
+
end
|
904
|
+
|
905
|
+
context "when removing" do
|
906
|
+
|
907
|
+
let(:criteria) do
|
908
|
+
Band.where(name: "Depeche Mode")
|
909
|
+
end
|
910
|
+
|
911
|
+
let!(:result) do
|
912
|
+
criteria.find_and_modify({}, remove: true)
|
913
|
+
end
|
914
|
+
|
915
|
+
it "returns the first matching document" do
|
916
|
+
expect(result).to eq(depeche)
|
917
|
+
end
|
918
|
+
|
919
|
+
it "deletes the document from the database" do
|
920
|
+
expect {
|
921
|
+
depeche.reload
|
922
|
+
}.to raise_error(Mongoid::Errors::DocumentNotFound)
|
923
|
+
end
|
924
|
+
end
|
925
|
+
end
|
926
|
+
|
927
|
+
context "when the selector does not match" do
|
928
|
+
|
929
|
+
let(:criteria) do
|
930
|
+
Band.where(name: "Placebo")
|
931
|
+
end
|
932
|
+
|
933
|
+
let(:result) do
|
934
|
+
criteria.find_and_modify("$inc" => { likes: 1 })
|
935
|
+
end
|
936
|
+
|
937
|
+
it "returns nil" do
|
938
|
+
expect(result).to be_nil
|
939
|
+
end
|
940
|
+
end
|
941
|
+
end
|
942
|
+
|
943
|
+
describe "#freeze" do
|
944
|
+
|
945
|
+
let(:criteria) do
|
946
|
+
Band.all
|
947
|
+
end
|
948
|
+
|
949
|
+
before do
|
950
|
+
criteria.freeze
|
951
|
+
end
|
952
|
+
|
953
|
+
it "freezes the criteria" do
|
954
|
+
expect(criteria).to be_frozen
|
955
|
+
end
|
956
|
+
|
957
|
+
it "initializes inclusions" do
|
958
|
+
expect(criteria.inclusions).to be_empty
|
959
|
+
end
|
960
|
+
|
961
|
+
it "initializes the context" do
|
962
|
+
expect(criteria.context).to_not be_nil
|
963
|
+
end
|
964
|
+
end
|
965
|
+
|
966
|
+
describe "#geo_near" do
|
967
|
+
|
968
|
+
before do
|
969
|
+
Bar.create_indexes
|
970
|
+
end
|
971
|
+
|
972
|
+
let!(:match) do
|
973
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
974
|
+
end
|
975
|
+
|
976
|
+
let(:criteria) do
|
977
|
+
Bar.geo_near([ 52, 13 ]).max_distance(10).spherical
|
978
|
+
end
|
979
|
+
|
980
|
+
it "returns the matching documents" do
|
981
|
+
expect(criteria).to eq([ match ])
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
describe "#gt" do
|
986
|
+
|
987
|
+
let!(:match) do
|
988
|
+
Band.create(member_count: 5)
|
989
|
+
end
|
990
|
+
|
991
|
+
let!(:non_match) do
|
992
|
+
Band.create(member_count: 1)
|
993
|
+
end
|
994
|
+
|
995
|
+
let(:criteria) do
|
996
|
+
Band.gt(member_count: 4)
|
997
|
+
end
|
998
|
+
|
999
|
+
it "returns the matching documents" do
|
1000
|
+
expect(criteria).to eq([ match ])
|
1001
|
+
end
|
1002
|
+
end
|
1003
|
+
|
1004
|
+
describe "#gte" do
|
1005
|
+
|
1006
|
+
let!(:match) do
|
1007
|
+
Band.create(member_count: 5)
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
let!(:non_match) do
|
1011
|
+
Band.create(member_count: 1)
|
1012
|
+
end
|
1013
|
+
|
1014
|
+
let(:criteria) do
|
1015
|
+
Band.gte(member_count: 5)
|
1016
|
+
end
|
1017
|
+
|
1018
|
+
it "returns the matching documents" do
|
1019
|
+
expect(criteria).to eq([ match ])
|
1020
|
+
end
|
1021
|
+
end
|
1022
|
+
|
1023
|
+
[ :in, :any_in ].each do |method|
|
1024
|
+
|
1025
|
+
describe "\##{method}" do
|
1026
|
+
|
1027
|
+
context "when querying on a normal field" do
|
1028
|
+
|
1029
|
+
let!(:match) do
|
1030
|
+
Band.create(genres: [ "electro", "dub" ])
|
1031
|
+
end
|
1032
|
+
|
1033
|
+
let!(:non_match) do
|
1034
|
+
Band.create(genres: [ "house" ])
|
1035
|
+
end
|
1036
|
+
|
1037
|
+
let(:criteria) do
|
1038
|
+
Band.send(method, genres: [ "dub" ])
|
1039
|
+
end
|
1040
|
+
|
1041
|
+
it "returns the matching documents" do
|
1042
|
+
expect(criteria).to eq([ match ])
|
1043
|
+
end
|
1044
|
+
end
|
1045
|
+
|
1046
|
+
context "when querying on a foreign key" do
|
1047
|
+
|
1048
|
+
let(:id) do
|
1049
|
+
Moped::BSON::ObjectId.new
|
1050
|
+
end
|
1051
|
+
|
1052
|
+
let!(:match_one) do
|
1053
|
+
Person.create(preference_ids: [ id ])
|
1054
|
+
end
|
1055
|
+
|
1056
|
+
context "when providing valid ids" do
|
1057
|
+
|
1058
|
+
let(:criteria) do
|
1059
|
+
Person.send(method, preference_ids: [ id ])
|
1060
|
+
end
|
1061
|
+
|
1062
|
+
it "returns the matching documents" do
|
1063
|
+
expect(criteria).to eq([ match_one ])
|
1064
|
+
end
|
1065
|
+
end
|
1066
|
+
|
1067
|
+
context "when providing empty strings" do
|
1068
|
+
|
1069
|
+
let(:criteria) do
|
1070
|
+
Person.send(method, preference_ids: [ id, "" ])
|
1071
|
+
end
|
1072
|
+
|
1073
|
+
it "returns the matching documents" do
|
1074
|
+
expect(criteria).to eq([ match_one ])
|
1075
|
+
end
|
1076
|
+
end
|
1077
|
+
|
1078
|
+
context "when providing nils" do
|
1079
|
+
|
1080
|
+
context "when the relation is a many to many" do
|
1081
|
+
|
1082
|
+
let(:criteria) do
|
1083
|
+
Person.send(method, preference_ids: [ id, nil ])
|
1084
|
+
end
|
1085
|
+
|
1086
|
+
it "returns the matching documents" do
|
1087
|
+
expect(criteria).to eq([ match_one ])
|
1088
|
+
end
|
1089
|
+
end
|
1090
|
+
|
1091
|
+
context "when the relation is a one to one" do
|
1092
|
+
|
1093
|
+
let!(:game) do
|
1094
|
+
Game.create
|
1095
|
+
end
|
1096
|
+
|
1097
|
+
let(:criteria) do
|
1098
|
+
Game.send(method, person_id: [ nil ])
|
1099
|
+
end
|
1100
|
+
|
1101
|
+
it "returns the matching documents" do
|
1102
|
+
expect(criteria).to eq([ game ])
|
1103
|
+
end
|
1104
|
+
end
|
1105
|
+
end
|
1106
|
+
end
|
1107
|
+
end
|
1108
|
+
end
|
1109
|
+
|
1110
|
+
describe "#initialize" do
|
1111
|
+
|
1112
|
+
let(:criteria) do
|
1113
|
+
described_class.new(Band)
|
1114
|
+
end
|
1115
|
+
|
1116
|
+
it "sets the class" do
|
1117
|
+
expect(criteria.klass).to eq(Band)
|
1118
|
+
end
|
1119
|
+
|
1120
|
+
it "sets the aliased fields" do
|
1121
|
+
expect(criteria.aliased_fields).to eq(Band.aliased_fields)
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
it "sets the serializers" do
|
1125
|
+
expect(criteria.serializers).to eq(Band.fields)
|
1126
|
+
end
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
describe "#includes" do
|
1130
|
+
|
1131
|
+
before do
|
1132
|
+
Mongoid.identity_map_enabled = true
|
1133
|
+
end
|
1134
|
+
|
1135
|
+
after do
|
1136
|
+
Mongoid.identity_map_enabled = false
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
let!(:person) do
|
1140
|
+
Person.create
|
1141
|
+
end
|
1142
|
+
|
1143
|
+
context "when providing a name that is not a relation" do
|
1144
|
+
|
1145
|
+
it "raises an error" do
|
1146
|
+
expect {
|
1147
|
+
Person.includes(:members)
|
1148
|
+
}.to raise_error(Mongoid::Errors::InvalidIncludes)
|
1149
|
+
end
|
1150
|
+
end
|
1151
|
+
|
1152
|
+
context "when providing a hash" do
|
1153
|
+
|
1154
|
+
it "raises an error" do
|
1155
|
+
expect {
|
1156
|
+
Person.includes(preferences: :members)
|
1157
|
+
}.to raise_error(Mongoid::Errors::InvalidIncludes)
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
|
1161
|
+
context "when the models are inherited" do
|
1162
|
+
|
1163
|
+
before(:all) do
|
1164
|
+
class A
|
1165
|
+
include Mongoid::Document
|
1166
|
+
end
|
1167
|
+
|
1168
|
+
class B < A
|
1169
|
+
belongs_to :c
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
class C
|
1173
|
+
include Mongoid::Document
|
1174
|
+
has_one :b
|
1175
|
+
end
|
1176
|
+
end
|
1177
|
+
|
1178
|
+
after(:all) do
|
1179
|
+
Object.send(:remove_const, :A)
|
1180
|
+
Object.send(:remove_const, :B)
|
1181
|
+
Object.send(:remove_const, :C)
|
1182
|
+
end
|
1183
|
+
|
1184
|
+
context "when the includes is on the subclass" do
|
1185
|
+
|
1186
|
+
let!(:c_one) do
|
1187
|
+
C.create
|
1188
|
+
end
|
1189
|
+
|
1190
|
+
let!(:c_two) do
|
1191
|
+
C.create
|
1192
|
+
end
|
1193
|
+
|
1194
|
+
let!(:b) do
|
1195
|
+
B.create(c: c_two)
|
1196
|
+
end
|
1197
|
+
|
1198
|
+
before do
|
1199
|
+
Mongoid::IdentityMap.clear
|
1200
|
+
end
|
1201
|
+
|
1202
|
+
let!(:results) do
|
1203
|
+
C.includes(:b).entries.detect do |c|
|
1204
|
+
c.id == c_two.id
|
1205
|
+
end
|
1206
|
+
end
|
1207
|
+
|
1208
|
+
let(:from_map) do
|
1209
|
+
Mongoid::IdentityMap[B.collection_name][b.id]
|
1210
|
+
end
|
1211
|
+
|
1212
|
+
it "returns the correct documents" do
|
1213
|
+
expect(results).to eq(c_two)
|
1214
|
+
end
|
1215
|
+
|
1216
|
+
it "inserts the first document into the identity map" do
|
1217
|
+
expect(from_map).to eq(b)
|
1218
|
+
end
|
1219
|
+
|
1220
|
+
it "retrieves the document from the identity map" do
|
1221
|
+
expect(results.b).to equal(from_map)
|
1222
|
+
end
|
1223
|
+
end
|
1224
|
+
end
|
1225
|
+
|
1226
|
+
context "when the models are inherited from another one model" do
|
1227
|
+
|
1228
|
+
context "when the relation is a has_one" do
|
1229
|
+
|
1230
|
+
before(:all) do
|
1231
|
+
class A
|
1232
|
+
include Mongoid::Document
|
1233
|
+
end
|
1234
|
+
|
1235
|
+
class B < A
|
1236
|
+
belongs_to :d
|
1237
|
+
end
|
1238
|
+
|
1239
|
+
class C < A
|
1240
|
+
belongs_to :d
|
1241
|
+
end
|
1242
|
+
|
1243
|
+
class D
|
1244
|
+
include Mongoid::Document
|
1245
|
+
has_one :b
|
1246
|
+
has_one :c
|
1247
|
+
end
|
1248
|
+
end
|
1249
|
+
|
1250
|
+
after(:all) do
|
1251
|
+
Object.send(:remove_const, :A)
|
1252
|
+
Object.send(:remove_const, :B)
|
1253
|
+
Object.send(:remove_const, :C)
|
1254
|
+
Object.send(:remove_const, :D)
|
1255
|
+
end
|
1256
|
+
|
1257
|
+
context "when the includes is on the several relations" do
|
1258
|
+
|
1259
|
+
let!(:d_one) do
|
1260
|
+
D.create
|
1261
|
+
end
|
1262
|
+
|
1263
|
+
let!(:d_two) do
|
1264
|
+
D.create
|
1265
|
+
end
|
1266
|
+
|
1267
|
+
let!(:b) do
|
1268
|
+
B.create(d: d_two)
|
1269
|
+
end
|
1270
|
+
|
1271
|
+
let!(:c) do
|
1272
|
+
C.create(d: d_two)
|
1273
|
+
end
|
1274
|
+
|
1275
|
+
before do
|
1276
|
+
Mongoid::IdentityMap.clear
|
1277
|
+
end
|
1278
|
+
|
1279
|
+
let!(:results) do
|
1280
|
+
D.includes(:b, :c).entries.detect do |d|
|
1281
|
+
d.id == d_two.id
|
1282
|
+
end
|
1283
|
+
end
|
1284
|
+
|
1285
|
+
let(:from_map_b) do
|
1286
|
+
Mongoid::IdentityMap[B.collection_name][b.id]
|
1287
|
+
end
|
1288
|
+
|
1289
|
+
let(:from_map_c) do
|
1290
|
+
Mongoid::IdentityMap[C.collection_name][c.id]
|
1291
|
+
end
|
1292
|
+
|
1293
|
+
it "returns the correct documents" do
|
1294
|
+
expect(results).to eq(d_two)
|
1295
|
+
end
|
1296
|
+
|
1297
|
+
it "inserts the b document into the identity map" do
|
1298
|
+
expect(from_map_b).to eq(b)
|
1299
|
+
end
|
1300
|
+
|
1301
|
+
it "inserts the c document into the identity map" do
|
1302
|
+
expect(from_map_c).to eq(c)
|
1303
|
+
end
|
1304
|
+
|
1305
|
+
it "retrieves the b document from the identity map" do
|
1306
|
+
expect(results.b).to equal(from_map_b)
|
1307
|
+
end
|
1308
|
+
|
1309
|
+
it "retrieves the c document from the identity map" do
|
1310
|
+
expect(results.c).to equal(from_map_c)
|
1311
|
+
end
|
1312
|
+
end
|
1313
|
+
end
|
1314
|
+
|
1315
|
+
context "when the relation is a has_many" do
|
1316
|
+
|
1317
|
+
before(:all) do
|
1318
|
+
class A
|
1319
|
+
include Mongoid::Document
|
1320
|
+
end
|
1321
|
+
|
1322
|
+
class B < A
|
1323
|
+
belongs_to :d
|
1324
|
+
end
|
1325
|
+
|
1326
|
+
class C < A
|
1327
|
+
belongs_to :d
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
class D
|
1331
|
+
include Mongoid::Document
|
1332
|
+
has_many :b
|
1333
|
+
has_many :c
|
1334
|
+
end
|
1335
|
+
end
|
1336
|
+
|
1337
|
+
after(:all) do
|
1338
|
+
Object.send(:remove_const, :A)
|
1339
|
+
Object.send(:remove_const, :B)
|
1340
|
+
Object.send(:remove_const, :C)
|
1341
|
+
Object.send(:remove_const, :D)
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
context "when the includes is on the several relations" do
|
1345
|
+
|
1346
|
+
let!(:d_one) do
|
1347
|
+
D.create
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
let!(:d_two) do
|
1351
|
+
D.create
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
let!(:bs) do
|
1355
|
+
2.times.map { B.create(d: d_two) }
|
1356
|
+
end
|
1357
|
+
|
1358
|
+
let!(:cs) do
|
1359
|
+
2.times.map { C.create(d: d_two) }
|
1360
|
+
end
|
1361
|
+
|
1362
|
+
before do
|
1363
|
+
Mongoid::IdentityMap.clear
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
let!(:results) do
|
1367
|
+
D.includes(:b, :c).entries.detect do |d|
|
1368
|
+
d.id == d_two.id
|
1369
|
+
end
|
1370
|
+
end
|
1371
|
+
|
1372
|
+
let(:from_map_bs) do
|
1373
|
+
bs.map { |b| Mongoid::IdentityMap[B.collection_name][b.id] }
|
1374
|
+
end
|
1375
|
+
|
1376
|
+
let(:from_map_cs) do
|
1377
|
+
cs.map { |c| Mongoid::IdentityMap[C.collection_name][c.id] }
|
1378
|
+
end
|
1379
|
+
|
1380
|
+
it "returns the correct documents" do
|
1381
|
+
expect(results).to eq(d_two)
|
1382
|
+
end
|
1383
|
+
|
1384
|
+
it "inserts the b documents into the identity map" do
|
1385
|
+
expect(from_map_bs).to eq(bs)
|
1386
|
+
end
|
1387
|
+
|
1388
|
+
it "inserts the c documents into the identity map" do
|
1389
|
+
expect(from_map_cs).to eq(cs)
|
1390
|
+
end
|
1391
|
+
|
1392
|
+
it "retrieves the b documents from the identity map" do
|
1393
|
+
expect(results.b).to match_array(from_map_bs)
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
it "retrieves the c documents from the identity map" do
|
1397
|
+
expect(results.c).to match_array(from_map_cs)
|
1398
|
+
end
|
1399
|
+
end
|
1400
|
+
end
|
1401
|
+
end
|
1402
|
+
|
1403
|
+
context "when including the same metadata multiple times" do
|
1404
|
+
|
1405
|
+
let(:criteria) do
|
1406
|
+
Person.all.includes(:posts, :posts).includes(:posts)
|
1407
|
+
end
|
1408
|
+
|
1409
|
+
let(:metadata) do
|
1410
|
+
Person.reflect_on_association(:posts)
|
1411
|
+
end
|
1412
|
+
|
1413
|
+
it "does not duplicate the metadata in the inclusions" do
|
1414
|
+
expect(criteria.inclusions).to eq([ metadata ])
|
1415
|
+
end
|
1416
|
+
end
|
1417
|
+
|
1418
|
+
context "when mapping the results more than once" do
|
1419
|
+
|
1420
|
+
before do
|
1421
|
+
Mongoid::IdentityMap.clear
|
1422
|
+
end
|
1423
|
+
|
1424
|
+
let!(:post) do
|
1425
|
+
person.posts.create(title: "one")
|
1426
|
+
end
|
1427
|
+
|
1428
|
+
let(:criteria) do
|
1429
|
+
Post.includes(:person)
|
1430
|
+
end
|
1431
|
+
|
1432
|
+
let!(:results) do
|
1433
|
+
criteria.map { |doc| doc }
|
1434
|
+
criteria.map { |doc| doc }
|
1435
|
+
end
|
1436
|
+
|
1437
|
+
it "returns the proper results" do
|
1438
|
+
expect(results.first.title).to eq("one")
|
1439
|
+
end
|
1440
|
+
end
|
1441
|
+
|
1442
|
+
context "when including a belongs to relation" do
|
1443
|
+
|
1444
|
+
context "when the criteria is from an embedded relation" do
|
1445
|
+
|
1446
|
+
let(:peep) do
|
1447
|
+
Person.create
|
1448
|
+
end
|
1449
|
+
|
1450
|
+
let!(:address_one) do
|
1451
|
+
peep.addresses.create(street: "rosenthaler")
|
1452
|
+
end
|
1453
|
+
|
1454
|
+
let!(:address_two) do
|
1455
|
+
peep.addresses.create(street: "weinmeister")
|
1456
|
+
end
|
1457
|
+
|
1458
|
+
let!(:depeche) do
|
1459
|
+
Band.create!(name: "Depeche Mode")
|
1460
|
+
end
|
1461
|
+
|
1462
|
+
let!(:tool) do
|
1463
|
+
Band.create!(name: "Tool")
|
1464
|
+
end
|
1465
|
+
|
1466
|
+
before do
|
1467
|
+
address_one.band = depeche
|
1468
|
+
address_two.band = tool
|
1469
|
+
address_one.save
|
1470
|
+
address_two.save
|
1471
|
+
end
|
1472
|
+
|
1473
|
+
context "when calling first" do
|
1474
|
+
|
1475
|
+
before do
|
1476
|
+
Mongoid::IdentityMap.clear
|
1477
|
+
end
|
1478
|
+
|
1479
|
+
let(:criteria) do
|
1480
|
+
peep.reload.addresses.includes(:band)
|
1481
|
+
end
|
1482
|
+
|
1483
|
+
let(:context) do
|
1484
|
+
criteria.context
|
1485
|
+
end
|
1486
|
+
|
1487
|
+
before do
|
1488
|
+
context.should_receive(:eager_load_one).with(address_one).once.and_call_original
|
1489
|
+
end
|
1490
|
+
|
1491
|
+
let!(:document) do
|
1492
|
+
criteria.first
|
1493
|
+
end
|
1494
|
+
|
1495
|
+
let(:eager_loaded) do
|
1496
|
+
Mongoid::IdentityMap[Band.collection_name]
|
1497
|
+
end
|
1498
|
+
|
1499
|
+
it "eager loads the first document" do
|
1500
|
+
expect(eager_loaded[depeche.id]).to eq(depeche)
|
1501
|
+
end
|
1502
|
+
|
1503
|
+
it "does not eager load the last document" do
|
1504
|
+
expect(eager_loaded[tool.id]).to be_nil
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
it "returns the document" do
|
1508
|
+
expect(document).to eq(address_one)
|
1509
|
+
end
|
1510
|
+
end
|
1511
|
+
|
1512
|
+
context "when calling last" do
|
1513
|
+
|
1514
|
+
before do
|
1515
|
+
Mongoid::IdentityMap.clear
|
1516
|
+
end
|
1517
|
+
|
1518
|
+
let(:criteria) do
|
1519
|
+
peep.reload.addresses.includes(:band)
|
1520
|
+
end
|
1521
|
+
|
1522
|
+
let(:context) do
|
1523
|
+
criteria.context
|
1524
|
+
end
|
1525
|
+
|
1526
|
+
before do
|
1527
|
+
context.should_receive(:eager_load_one).with(address_two).once.and_call_original
|
1528
|
+
end
|
1529
|
+
|
1530
|
+
let!(:document) do
|
1531
|
+
criteria.last
|
1532
|
+
end
|
1533
|
+
|
1534
|
+
let(:eager_loaded) do
|
1535
|
+
Mongoid::IdentityMap[Band.collection_name]
|
1536
|
+
end
|
1537
|
+
|
1538
|
+
it "does not eager load the first document" do
|
1539
|
+
expect(eager_loaded[depeche.id]).to be_nil
|
1540
|
+
end
|
1541
|
+
|
1542
|
+
it "eager loads the last document" do
|
1543
|
+
expect(eager_loaded[tool.id]).to eq(tool)
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
it "returns the document" do
|
1547
|
+
expect(document).to eq(address_two)
|
1548
|
+
end
|
1549
|
+
end
|
1550
|
+
|
1551
|
+
context "when iterating all documents" do
|
1552
|
+
|
1553
|
+
before do
|
1554
|
+
Mongoid::IdentityMap.clear
|
1555
|
+
end
|
1556
|
+
|
1557
|
+
let(:criteria) do
|
1558
|
+
peep.reload.addresses.includes(:band)
|
1559
|
+
end
|
1560
|
+
|
1561
|
+
let(:context) do
|
1562
|
+
criteria.context
|
1563
|
+
end
|
1564
|
+
|
1565
|
+
before do
|
1566
|
+
context.
|
1567
|
+
should_receive(:eager_load).
|
1568
|
+
with([ address_one, address_two ]).
|
1569
|
+
once.
|
1570
|
+
and_call_original
|
1571
|
+
end
|
1572
|
+
|
1573
|
+
let!(:documents) do
|
1574
|
+
criteria.to_a
|
1575
|
+
end
|
1576
|
+
|
1577
|
+
let(:eager_loaded) do
|
1578
|
+
Mongoid::IdentityMap[Band.collection_name]
|
1579
|
+
end
|
1580
|
+
|
1581
|
+
it "eager loads the first document" do
|
1582
|
+
expect(eager_loaded[depeche.id]).to eq(depeche)
|
1583
|
+
end
|
1584
|
+
|
1585
|
+
it "eager loads the last document" do
|
1586
|
+
expect(eager_loaded[tool.id]).to eq(tool)
|
1587
|
+
end
|
1588
|
+
|
1589
|
+
it "returns the documents" do
|
1590
|
+
expect(documents).to eq([ address_one, address_two ])
|
1591
|
+
end
|
1592
|
+
end
|
1593
|
+
end
|
1594
|
+
|
1595
|
+
context "when the criteria is from the root" do
|
1596
|
+
|
1597
|
+
let!(:person_two) do
|
1598
|
+
Person.create
|
1599
|
+
end
|
1600
|
+
|
1601
|
+
let!(:post_one) do
|
1602
|
+
person.posts.create(title: "one")
|
1603
|
+
end
|
1604
|
+
|
1605
|
+
let!(:post_two) do
|
1606
|
+
person_two.posts.create(title: "two")
|
1607
|
+
end
|
1608
|
+
|
1609
|
+
before do
|
1610
|
+
Mongoid::IdentityMap.clear
|
1611
|
+
end
|
1612
|
+
|
1613
|
+
context "when calling first" do
|
1614
|
+
|
1615
|
+
let!(:criteria) do
|
1616
|
+
Post.includes(:person)
|
1617
|
+
end
|
1618
|
+
|
1619
|
+
let!(:context) do
|
1620
|
+
criteria.context
|
1621
|
+
end
|
1622
|
+
|
1623
|
+
before do
|
1624
|
+
context.should_receive(:eager_load_one).with(post_one).once.and_call_original
|
1625
|
+
end
|
1626
|
+
|
1627
|
+
let!(:document) do
|
1628
|
+
criteria.first
|
1629
|
+
end
|
1630
|
+
|
1631
|
+
it "eager loads for the first document" do
|
1632
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person.id]).to eq(person)
|
1633
|
+
end
|
1634
|
+
|
1635
|
+
it "does not eager loads for the last document" do
|
1636
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person_two.id]).to be_nil
|
1637
|
+
end
|
1638
|
+
|
1639
|
+
it "returns the first document" do
|
1640
|
+
expect(document).to eq(post_one)
|
1641
|
+
end
|
1642
|
+
end
|
1643
|
+
|
1644
|
+
context "when calling last" do
|
1645
|
+
|
1646
|
+
let!(:criteria) do
|
1647
|
+
Post.includes(:person)
|
1648
|
+
end
|
1649
|
+
|
1650
|
+
let!(:context) do
|
1651
|
+
criteria.context
|
1652
|
+
end
|
1653
|
+
|
1654
|
+
before do
|
1655
|
+
context.should_receive(:eager_load_one).with(post_two).once.and_call_original
|
1656
|
+
end
|
1657
|
+
|
1658
|
+
let!(:document) do
|
1659
|
+
criteria.last
|
1660
|
+
end
|
1661
|
+
|
1662
|
+
it "eager loads for the first document" do
|
1663
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person_two.id]).to eq(person_two)
|
1664
|
+
end
|
1665
|
+
|
1666
|
+
it "does not eager loads for the last document" do
|
1667
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person.id]).to be_nil
|
1668
|
+
end
|
1669
|
+
|
1670
|
+
it "returns the last document" do
|
1671
|
+
expect(document).to eq(post_two)
|
1672
|
+
end
|
1673
|
+
end
|
1674
|
+
end
|
1675
|
+
end
|
1676
|
+
|
1677
|
+
context "when providing inclusions to the default scope" do
|
1678
|
+
|
1679
|
+
before do
|
1680
|
+
Person.default_scope(Person.includes(:posts))
|
1681
|
+
end
|
1682
|
+
|
1683
|
+
after do
|
1684
|
+
Person.default_scoping = nil
|
1685
|
+
end
|
1686
|
+
|
1687
|
+
let!(:post_one) do
|
1688
|
+
person.posts.create(title: "one")
|
1689
|
+
end
|
1690
|
+
|
1691
|
+
let!(:post_two) do
|
1692
|
+
person.posts.create(title: "two")
|
1693
|
+
end
|
1694
|
+
|
1695
|
+
context "when the criteria has no options" do
|
1696
|
+
|
1697
|
+
before do
|
1698
|
+
Mongoid::IdentityMap.clear
|
1699
|
+
end
|
1700
|
+
|
1701
|
+
let!(:criteria) do
|
1702
|
+
Person.all
|
1703
|
+
end
|
1704
|
+
|
1705
|
+
let!(:context) do
|
1706
|
+
criteria.context
|
1707
|
+
end
|
1708
|
+
|
1709
|
+
before do
|
1710
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
1711
|
+
end
|
1712
|
+
|
1713
|
+
let!(:documents) do
|
1714
|
+
criteria.entries
|
1715
|
+
end
|
1716
|
+
|
1717
|
+
it "returns the correct documents" do
|
1718
|
+
expect(documents).to eq([ person ])
|
1719
|
+
end
|
1720
|
+
|
1721
|
+
it "inserts the first document into the identity map" do
|
1722
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
1723
|
+
end
|
1724
|
+
|
1725
|
+
it "inserts the second document into the identity map" do
|
1726
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
1727
|
+
end
|
1728
|
+
|
1729
|
+
context "when executing the query twice" do
|
1730
|
+
|
1731
|
+
let!(:new_criteria) do
|
1732
|
+
Person.where(id: person.id)
|
1733
|
+
end
|
1734
|
+
|
1735
|
+
let!(:new_context) do
|
1736
|
+
new_criteria.context
|
1737
|
+
end
|
1738
|
+
|
1739
|
+
before do
|
1740
|
+
new_context.should_receive(:eager_load_one).with(person).once.and_call_original
|
1741
|
+
end
|
1742
|
+
|
1743
|
+
let!(:from_db) do
|
1744
|
+
new_criteria.first
|
1745
|
+
end
|
1746
|
+
|
1747
|
+
let(:mapped) do
|
1748
|
+
Mongoid::IdentityMap[Post.collection_name][{"person_id" => person.id}]
|
1749
|
+
end
|
1750
|
+
|
1751
|
+
it "does not duplicate documents in the relation" do
|
1752
|
+
expect(person.posts.size).to eq(2)
|
1753
|
+
end
|
1754
|
+
|
1755
|
+
it "does not duplicate documents in the map" do
|
1756
|
+
expect(mapped.size).to eq(2)
|
1757
|
+
end
|
1758
|
+
end
|
1759
|
+
end
|
1760
|
+
|
1761
|
+
context "when calling first on the criteria" do
|
1762
|
+
|
1763
|
+
before do
|
1764
|
+
Mongoid::IdentityMap.clear
|
1765
|
+
end
|
1766
|
+
|
1767
|
+
let(:criteria) do
|
1768
|
+
Person.all
|
1769
|
+
end
|
1770
|
+
|
1771
|
+
let!(:context) do
|
1772
|
+
criteria.context
|
1773
|
+
end
|
1774
|
+
|
1775
|
+
before do
|
1776
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
1777
|
+
end
|
1778
|
+
|
1779
|
+
let!(:from_db) do
|
1780
|
+
criteria.first
|
1781
|
+
end
|
1782
|
+
|
1783
|
+
it "returns the correct documents" do
|
1784
|
+
expect(from_db).to eq(person)
|
1785
|
+
end
|
1786
|
+
|
1787
|
+
it "inserts the first document into the identity map" do
|
1788
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
1789
|
+
end
|
1790
|
+
|
1791
|
+
it "inserts the second document into the identity map" do
|
1792
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
1793
|
+
end
|
1794
|
+
end
|
1795
|
+
|
1796
|
+
context "when calling last on the criteria" do
|
1797
|
+
|
1798
|
+
before do
|
1799
|
+
Mongoid::IdentityMap.clear
|
1800
|
+
end
|
1801
|
+
|
1802
|
+
let(:criteria) do
|
1803
|
+
Person.all
|
1804
|
+
end
|
1805
|
+
|
1806
|
+
let!(:context) do
|
1807
|
+
criteria.context
|
1808
|
+
end
|
1809
|
+
|
1810
|
+
before do
|
1811
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
1812
|
+
end
|
1813
|
+
|
1814
|
+
let!(:from_db) do
|
1815
|
+
criteria.last
|
1816
|
+
end
|
1817
|
+
|
1818
|
+
it "returns the correct documents" do
|
1819
|
+
expect(from_db).to eq(person)
|
1820
|
+
end
|
1821
|
+
|
1822
|
+
it "inserts the first document into the identity map" do
|
1823
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
1824
|
+
end
|
1825
|
+
|
1826
|
+
it "inserts the second document into the identity map" do
|
1827
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
1828
|
+
end
|
1829
|
+
end
|
1830
|
+
|
1831
|
+
context "when the criteria has limiting options" do
|
1832
|
+
|
1833
|
+
let!(:person_two) do
|
1834
|
+
Person.create
|
1835
|
+
end
|
1836
|
+
|
1837
|
+
let!(:post_three) do
|
1838
|
+
person_two.posts.create(title: "three")
|
1839
|
+
end
|
1840
|
+
|
1841
|
+
before do
|
1842
|
+
Mongoid::IdentityMap.clear
|
1843
|
+
end
|
1844
|
+
|
1845
|
+
let!(:criteria) do
|
1846
|
+
Person.asc(:_id).limit(1)
|
1847
|
+
end
|
1848
|
+
|
1849
|
+
let(:context) do
|
1850
|
+
criteria.context
|
1851
|
+
end
|
1852
|
+
|
1853
|
+
before do
|
1854
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
1855
|
+
end
|
1856
|
+
|
1857
|
+
let!(:documents) do
|
1858
|
+
criteria.entries
|
1859
|
+
end
|
1860
|
+
|
1861
|
+
it "returns the correct documents" do
|
1862
|
+
expect(criteria).to eq([ person ])
|
1863
|
+
end
|
1864
|
+
|
1865
|
+
it "inserts the first document into the identity map" do
|
1866
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
1867
|
+
end
|
1868
|
+
|
1869
|
+
it "inserts the second document into the identity map" do
|
1870
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
1871
|
+
end
|
1872
|
+
|
1873
|
+
it "does not insert the third post into the identity map" do
|
1874
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_three.id]).to be_nil
|
1875
|
+
end
|
1876
|
+
end
|
1877
|
+
end
|
1878
|
+
|
1879
|
+
context "when including a has and belongs to many" do
|
1880
|
+
|
1881
|
+
let!(:preference_one) do
|
1882
|
+
person.preferences.create(name: "one")
|
1883
|
+
end
|
1884
|
+
|
1885
|
+
let!(:preference_two) do
|
1886
|
+
person.preferences.create(name: "two")
|
1887
|
+
end
|
1888
|
+
|
1889
|
+
context "when the criteria has no options" do
|
1890
|
+
|
1891
|
+
before do
|
1892
|
+
Mongoid::IdentityMap.clear
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
let!(:criteria) do
|
1896
|
+
Person.includes(:preferences)
|
1897
|
+
end
|
1898
|
+
|
1899
|
+
let(:context) do
|
1900
|
+
criteria.context
|
1901
|
+
end
|
1902
|
+
|
1903
|
+
before do
|
1904
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
1905
|
+
end
|
1906
|
+
|
1907
|
+
let!(:documents) do
|
1908
|
+
criteria.entries
|
1909
|
+
end
|
1910
|
+
|
1911
|
+
it "returns the correct documents" do
|
1912
|
+
expect(documents).to eq([ person ])
|
1913
|
+
end
|
1914
|
+
|
1915
|
+
let(:preference_map) do
|
1916
|
+
Mongoid::IdentityMap[Preference.collection_name]
|
1917
|
+
end
|
1918
|
+
|
1919
|
+
it "inserts the first document into the identity map" do
|
1920
|
+
expect(preference_map[preference_one.id]).to eq(preference_one)
|
1921
|
+
end
|
1922
|
+
|
1923
|
+
it "inserts the second document into the identity map" do
|
1924
|
+
expect(preference_map[preference_two.id]).to eq(preference_two)
|
1925
|
+
end
|
1926
|
+
end
|
1927
|
+
|
1928
|
+
context "when calling first on the criteria" do
|
1929
|
+
|
1930
|
+
before do
|
1931
|
+
Mongoid::IdentityMap.clear
|
1932
|
+
end
|
1933
|
+
|
1934
|
+
let!(:criteria) do
|
1935
|
+
Person.includes(:preferences)
|
1936
|
+
end
|
1937
|
+
|
1938
|
+
let(:context) do
|
1939
|
+
criteria.context
|
1940
|
+
end
|
1941
|
+
|
1942
|
+
before do
|
1943
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
1944
|
+
end
|
1945
|
+
|
1946
|
+
let!(:from_db) do
|
1947
|
+
criteria.first
|
1948
|
+
end
|
1949
|
+
|
1950
|
+
it "returns the correct documents" do
|
1951
|
+
expect(from_db).to eq(person)
|
1952
|
+
end
|
1953
|
+
|
1954
|
+
let(:preference_map) do
|
1955
|
+
Mongoid::IdentityMap[Preference.collection_name]
|
1956
|
+
end
|
1957
|
+
|
1958
|
+
it "inserts the first document into the identity map" do
|
1959
|
+
expect(preference_map[preference_one.id]).to eq(preference_one)
|
1960
|
+
end
|
1961
|
+
|
1962
|
+
it "inserts the second document into the identity map" do
|
1963
|
+
expect(preference_map[preference_two.id]).to eq(preference_two)
|
1964
|
+
end
|
1965
|
+
end
|
1966
|
+
|
1967
|
+
context "when calling last on the criteria" do
|
1968
|
+
|
1969
|
+
before do
|
1970
|
+
Mongoid::IdentityMap.clear
|
1971
|
+
end
|
1972
|
+
|
1973
|
+
let!(:criteria) do
|
1974
|
+
Person.includes(:preferences)
|
1975
|
+
end
|
1976
|
+
|
1977
|
+
let(:context) do
|
1978
|
+
criteria.context
|
1979
|
+
end
|
1980
|
+
|
1981
|
+
before do
|
1982
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
1983
|
+
end
|
1984
|
+
|
1985
|
+
let!(:from_db) do
|
1986
|
+
criteria.last
|
1987
|
+
end
|
1988
|
+
|
1989
|
+
it "returns the correct documents" do
|
1990
|
+
expect(from_db).to eq(person)
|
1991
|
+
end
|
1992
|
+
|
1993
|
+
let(:preference_map) do
|
1994
|
+
Mongoid::IdentityMap[Preference.collection_name]
|
1995
|
+
end
|
1996
|
+
|
1997
|
+
it "inserts the first document into the identity map" do
|
1998
|
+
expect(preference_map[preference_one.id]).to eq(preference_one)
|
1999
|
+
end
|
2000
|
+
|
2001
|
+
it "inserts the second document into the identity map" do
|
2002
|
+
expect(preference_map[preference_two.id]).to eq(preference_two)
|
2003
|
+
end
|
2004
|
+
end
|
2005
|
+
|
2006
|
+
context "when the criteria has limiting options" do
|
2007
|
+
|
2008
|
+
let!(:person_two) do
|
2009
|
+
Person.create
|
2010
|
+
end
|
2011
|
+
|
2012
|
+
let!(:preference_three) do
|
2013
|
+
person_two.preferences.create(name: "three")
|
2014
|
+
end
|
2015
|
+
|
2016
|
+
before do
|
2017
|
+
Mongoid::IdentityMap.clear
|
2018
|
+
end
|
2019
|
+
|
2020
|
+
let!(:criteria) do
|
2021
|
+
Person.includes(:preferences).asc(:_id).limit(1)
|
2022
|
+
end
|
2023
|
+
|
2024
|
+
let(:context) do
|
2025
|
+
criteria.context
|
2026
|
+
end
|
2027
|
+
|
2028
|
+
before do
|
2029
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2030
|
+
end
|
2031
|
+
|
2032
|
+
let!(:documents) do
|
2033
|
+
criteria.entries
|
2034
|
+
end
|
2035
|
+
|
2036
|
+
let(:preference_map) do
|
2037
|
+
Mongoid::IdentityMap[Preference.collection_name]
|
2038
|
+
end
|
2039
|
+
|
2040
|
+
it "returns the correct documents" do
|
2041
|
+
expect(documents).to eq([ person ])
|
2042
|
+
end
|
2043
|
+
|
2044
|
+
it "inserts the first document into the identity map" do
|
2045
|
+
expect(preference_map[preference_one.id]).to eq(preference_one)
|
2046
|
+
end
|
2047
|
+
|
2048
|
+
it "inserts the second document into the identity map" do
|
2049
|
+
expect(preference_map[preference_two.id]).to eq(preference_two)
|
2050
|
+
end
|
2051
|
+
|
2052
|
+
it "does not insert the third preference into the identity map" do
|
2053
|
+
expect(preference_map[preference_three.id]).to be_nil
|
2054
|
+
end
|
2055
|
+
end
|
2056
|
+
end
|
2057
|
+
|
2058
|
+
context "when including a has many" do
|
2059
|
+
|
2060
|
+
let!(:post_one) do
|
2061
|
+
person.posts.create(title: "one")
|
2062
|
+
end
|
2063
|
+
|
2064
|
+
let!(:post_two) do
|
2065
|
+
person.posts.create(title: "two")
|
2066
|
+
end
|
2067
|
+
|
2068
|
+
context "when the criteria has no options" do
|
2069
|
+
|
2070
|
+
before do
|
2071
|
+
Mongoid::IdentityMap.clear
|
2072
|
+
end
|
2073
|
+
|
2074
|
+
let!(:criteria) do
|
2075
|
+
Person.includes(:posts)
|
2076
|
+
end
|
2077
|
+
|
2078
|
+
let(:context) do
|
2079
|
+
criteria.context
|
2080
|
+
end
|
2081
|
+
|
2082
|
+
before do
|
2083
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2084
|
+
end
|
2085
|
+
|
2086
|
+
let!(:documents) do
|
2087
|
+
criteria.entries
|
2088
|
+
end
|
2089
|
+
|
2090
|
+
it "returns the correct documents" do
|
2091
|
+
expect(documents).to eq([ person ])
|
2092
|
+
end
|
2093
|
+
|
2094
|
+
it "inserts the first document into the identity map" do
|
2095
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
2096
|
+
end
|
2097
|
+
|
2098
|
+
it "inserts the second document into the identity map" do
|
2099
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
2100
|
+
end
|
2101
|
+
end
|
2102
|
+
|
2103
|
+
context "when calling first on the criteria" do
|
2104
|
+
|
2105
|
+
before do
|
2106
|
+
Mongoid::IdentityMap.clear
|
2107
|
+
end
|
2108
|
+
|
2109
|
+
let!(:criteria) do
|
2110
|
+
Person.includes(:posts)
|
2111
|
+
end
|
2112
|
+
|
2113
|
+
let(:context) do
|
2114
|
+
criteria.context
|
2115
|
+
end
|
2116
|
+
|
2117
|
+
before do
|
2118
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
2119
|
+
end
|
2120
|
+
|
2121
|
+
let!(:from_db) do
|
2122
|
+
criteria.first
|
2123
|
+
end
|
2124
|
+
|
2125
|
+
it "returns the correct documents" do
|
2126
|
+
expect(from_db).to eq(person)
|
2127
|
+
end
|
2128
|
+
|
2129
|
+
it "inserts the first document into the identity map" do
|
2130
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
2131
|
+
end
|
2132
|
+
|
2133
|
+
it "inserts the second document into the identity map" do
|
2134
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
2135
|
+
end
|
2136
|
+
|
2137
|
+
context "when subsequently getting all documents" do
|
2138
|
+
|
2139
|
+
before do
|
2140
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2141
|
+
end
|
2142
|
+
|
2143
|
+
let!(:documents) do
|
2144
|
+
criteria.entries
|
2145
|
+
end
|
2146
|
+
|
2147
|
+
it "returns the correct documents" do
|
2148
|
+
expect(documents).to eq([ person ])
|
2149
|
+
end
|
2150
|
+
end
|
2151
|
+
end
|
2152
|
+
|
2153
|
+
context "when calling last on the criteria" do
|
2154
|
+
|
2155
|
+
before do
|
2156
|
+
Mongoid::IdentityMap.clear
|
2157
|
+
end
|
2158
|
+
|
2159
|
+
let!(:criteria) do
|
2160
|
+
Person.includes(:posts)
|
2161
|
+
end
|
2162
|
+
|
2163
|
+
let(:context) do
|
2164
|
+
criteria.context
|
2165
|
+
end
|
2166
|
+
|
2167
|
+
before do
|
2168
|
+
context.should_receive(:eager_load_one).with(person).once.and_call_original
|
2169
|
+
end
|
2170
|
+
|
2171
|
+
let!(:from_db) do
|
2172
|
+
criteria.last
|
2173
|
+
end
|
2174
|
+
|
2175
|
+
it "returns the correct documents" do
|
2176
|
+
expect(from_db).to eq(person)
|
2177
|
+
end
|
2178
|
+
|
2179
|
+
it "inserts the first document into the identity map" do
|
2180
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
2181
|
+
end
|
2182
|
+
|
2183
|
+
it "inserts the second document into the identity map" do
|
2184
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
2185
|
+
end
|
2186
|
+
|
2187
|
+
context "when subsequently getting all documents" do
|
2188
|
+
|
2189
|
+
before do
|
2190
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2191
|
+
end
|
2192
|
+
|
2193
|
+
let!(:documents) do
|
2194
|
+
criteria.entries
|
2195
|
+
end
|
2196
|
+
|
2197
|
+
it "returns the correct documents" do
|
2198
|
+
expect(documents).to eq([ person ])
|
2199
|
+
end
|
2200
|
+
end
|
2201
|
+
end
|
2202
|
+
|
2203
|
+
context "when the criteria has limiting options" do
|
2204
|
+
|
2205
|
+
let!(:person_two) do
|
2206
|
+
Person.create
|
2207
|
+
end
|
2208
|
+
|
2209
|
+
let!(:post_three) do
|
2210
|
+
person_two.posts.create(title: "three")
|
2211
|
+
end
|
2212
|
+
|
2213
|
+
before do
|
2214
|
+
Mongoid::IdentityMap.clear
|
2215
|
+
end
|
2216
|
+
|
2217
|
+
let!(:criteria) do
|
2218
|
+
Person.includes(:posts).asc(:_id).limit(1)
|
2219
|
+
end
|
2220
|
+
|
2221
|
+
let(:context) do
|
2222
|
+
criteria.context
|
2223
|
+
end
|
2224
|
+
|
2225
|
+
before do
|
2226
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2227
|
+
end
|
2228
|
+
|
2229
|
+
let!(:documents) do
|
2230
|
+
criteria.entries
|
2231
|
+
end
|
2232
|
+
|
2233
|
+
it "returns the correct documents" do
|
2234
|
+
expect(documents).to eq([ person ])
|
2235
|
+
end
|
2236
|
+
|
2237
|
+
it "inserts the first document into the identity map" do
|
2238
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
2239
|
+
end
|
2240
|
+
|
2241
|
+
it "inserts the second document into the identity map" do
|
2242
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
2243
|
+
end
|
2244
|
+
|
2245
|
+
it "does not insert the third post into the identity map" do
|
2246
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_three.id]).to be_nil
|
2247
|
+
end
|
2248
|
+
end
|
2249
|
+
end
|
2250
|
+
|
2251
|
+
context "when including a has one" do
|
2252
|
+
|
2253
|
+
let!(:game_one) do
|
2254
|
+
person.create_game(name: "one")
|
2255
|
+
end
|
2256
|
+
|
2257
|
+
let!(:game_two) do
|
2258
|
+
person.create_game(name: "two")
|
2259
|
+
end
|
2260
|
+
|
2261
|
+
context "when the criteria has no options" do
|
2262
|
+
|
2263
|
+
before do
|
2264
|
+
Mongoid::IdentityMap.clear
|
2265
|
+
end
|
2266
|
+
|
2267
|
+
let!(:criteria) do
|
2268
|
+
Person.includes(:game)
|
2269
|
+
end
|
2270
|
+
|
2271
|
+
let(:context) do
|
2272
|
+
criteria.context
|
2273
|
+
end
|
2274
|
+
|
2275
|
+
before do
|
2276
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2277
|
+
end
|
2278
|
+
|
2279
|
+
let!(:documents) do
|
2280
|
+
criteria.entries
|
2281
|
+
end
|
2282
|
+
|
2283
|
+
it "returns the correct documents" do
|
2284
|
+
expect(documents).to eq([ person ])
|
2285
|
+
end
|
2286
|
+
|
2287
|
+
it "deletes the replaced document from the identity map" do
|
2288
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_one.id]).to be_nil
|
2289
|
+
end
|
2290
|
+
|
2291
|
+
it "inserts the second document into the identity map" do
|
2292
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_two.id]).to eq(game_two)
|
2293
|
+
end
|
2294
|
+
|
2295
|
+
context "when asking from map or db" do
|
2296
|
+
|
2297
|
+
let(:in_map) do
|
2298
|
+
Mongoid::IdentityMap[Game.collection_name][game_two.id]
|
2299
|
+
end
|
2300
|
+
|
2301
|
+
let(:game) do
|
2302
|
+
Game.where("person_id" => person.id).from_map_or_db
|
2303
|
+
end
|
2304
|
+
|
2305
|
+
it "returns the document from the map" do
|
2306
|
+
expect(game).to equal(in_map)
|
2307
|
+
end
|
2308
|
+
end
|
2309
|
+
end
|
2310
|
+
|
2311
|
+
context "when the criteria has limiting options" do
|
2312
|
+
|
2313
|
+
let!(:person_two) do
|
2314
|
+
Person.create
|
2315
|
+
end
|
2316
|
+
|
2317
|
+
let!(:game_three) do
|
2318
|
+
person_two.create_game(name: "Skyrim")
|
2319
|
+
end
|
2320
|
+
|
2321
|
+
before do
|
2322
|
+
Mongoid::IdentityMap.clear
|
2323
|
+
end
|
2324
|
+
|
2325
|
+
let!(:criteria) do
|
2326
|
+
Person.where(id: person.id).includes(:game).asc(:_id).limit(1)
|
2327
|
+
end
|
2328
|
+
|
2329
|
+
let(:context) do
|
2330
|
+
criteria.context
|
2331
|
+
end
|
2332
|
+
|
2333
|
+
before do
|
2334
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2335
|
+
end
|
2336
|
+
|
2337
|
+
let!(:documents) do
|
2338
|
+
criteria.entries
|
2339
|
+
end
|
2340
|
+
|
2341
|
+
it "returns the correct documents" do
|
2342
|
+
expect(documents).to eq([ person ])
|
2343
|
+
end
|
2344
|
+
|
2345
|
+
it "inserts the second document into the identity map" do
|
2346
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_two.id]).to eq(game_two)
|
2347
|
+
end
|
2348
|
+
|
2349
|
+
it "does not load the extra child into the map" do
|
2350
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_three.id]).to be_nil
|
2351
|
+
end
|
2352
|
+
end
|
2353
|
+
end
|
2354
|
+
|
2355
|
+
context "when including a belongs to" do
|
2356
|
+
|
2357
|
+
let(:person_two) do
|
2358
|
+
Person.create
|
2359
|
+
end
|
2360
|
+
|
2361
|
+
let!(:game_one) do
|
2362
|
+
person.create_game(name: "one")
|
2363
|
+
end
|
2364
|
+
|
2365
|
+
let!(:game_two) do
|
2366
|
+
person_two.create_game(name: "two")
|
2367
|
+
end
|
2368
|
+
|
2369
|
+
before do
|
2370
|
+
Mongoid::IdentityMap.clear
|
2371
|
+
end
|
2372
|
+
|
2373
|
+
context "when providing no options" do
|
2374
|
+
|
2375
|
+
let!(:criteria) do
|
2376
|
+
Game.includes(:person)
|
2377
|
+
end
|
2378
|
+
|
2379
|
+
let(:context) do
|
2380
|
+
criteria.context
|
2381
|
+
end
|
2382
|
+
|
2383
|
+
before do
|
2384
|
+
context.
|
2385
|
+
should_receive(:eager_load).
|
2386
|
+
with([ game_one, game_two ]).
|
2387
|
+
once.
|
2388
|
+
and_call_original
|
2389
|
+
end
|
2390
|
+
|
2391
|
+
let!(:documents) do
|
2392
|
+
criteria.entries
|
2393
|
+
end
|
2394
|
+
|
2395
|
+
it "returns the correct documents" do
|
2396
|
+
expect(criteria).to eq([ game_one, game_two ])
|
2397
|
+
end
|
2398
|
+
|
2399
|
+
it "inserts the first document into the identity map" do
|
2400
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person.id]).to eq(person)
|
2401
|
+
end
|
2402
|
+
|
2403
|
+
it "inserts the second document into the identity map" do
|
2404
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person_two.id]).to eq(person_two)
|
2405
|
+
end
|
2406
|
+
end
|
2407
|
+
|
2408
|
+
context "when the criteria has limiting options" do
|
2409
|
+
|
2410
|
+
let!(:criteria) do
|
2411
|
+
Game.where(id: game_one.id).includes(:person).asc(:_id).limit(1)
|
2412
|
+
end
|
2413
|
+
|
2414
|
+
let(:context) do
|
2415
|
+
criteria.context
|
2416
|
+
end
|
2417
|
+
|
2418
|
+
before do
|
2419
|
+
context.should_receive(:eager_load).with([ game_one ]).once.and_call_original
|
2420
|
+
end
|
2421
|
+
|
2422
|
+
let!(:documents) do
|
2423
|
+
criteria.entries
|
2424
|
+
end
|
2425
|
+
|
2426
|
+
it "returns the correct documents" do
|
2427
|
+
expect(documents).to eq([ game_one ])
|
2428
|
+
end
|
2429
|
+
|
2430
|
+
it "inserts the first document into the identity map" do
|
2431
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person.id]).to eq(person)
|
2432
|
+
end
|
2433
|
+
|
2434
|
+
it "does not load the documents outside of the limit" do
|
2435
|
+
expect(Mongoid::IdentityMap[Person.collection_name][person_two.id]).to be_nil
|
2436
|
+
end
|
2437
|
+
end
|
2438
|
+
end
|
2439
|
+
|
2440
|
+
context "when including multiples in the same criteria" do
|
2441
|
+
|
2442
|
+
let!(:post_one) do
|
2443
|
+
person.posts.create(title: "one")
|
2444
|
+
end
|
2445
|
+
|
2446
|
+
let!(:post_two) do
|
2447
|
+
person.posts.create(title: "two")
|
2448
|
+
end
|
2449
|
+
|
2450
|
+
let!(:game_one) do
|
2451
|
+
person.create_game(name: "one")
|
2452
|
+
end
|
2453
|
+
|
2454
|
+
let!(:game_two) do
|
2455
|
+
person.create_game(name: "two")
|
2456
|
+
end
|
2457
|
+
|
2458
|
+
before do
|
2459
|
+
Mongoid::IdentityMap.clear
|
2460
|
+
end
|
2461
|
+
|
2462
|
+
let!(:criteria) do
|
2463
|
+
Person.includes(:posts, :game)
|
2464
|
+
end
|
2465
|
+
|
2466
|
+
let(:context) do
|
2467
|
+
criteria.context
|
2468
|
+
end
|
2469
|
+
|
2470
|
+
before do
|
2471
|
+
context.should_receive(:eager_load).with([ person ]).once.and_call_original
|
2472
|
+
end
|
2473
|
+
|
2474
|
+
let!(:documents) do
|
2475
|
+
criteria.entries
|
2476
|
+
end
|
2477
|
+
|
2478
|
+
it "returns the correct documents" do
|
2479
|
+
expect(criteria).to eq([ person ])
|
2480
|
+
end
|
2481
|
+
|
2482
|
+
it "inserts the first has many document into the identity map" do
|
2483
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_one.id]).to eq(post_one)
|
2484
|
+
end
|
2485
|
+
|
2486
|
+
it "inserts the second has many document into the identity map" do
|
2487
|
+
expect(Mongoid::IdentityMap[Post.collection_name][post_two.id]).to eq(post_two)
|
2488
|
+
end
|
2489
|
+
|
2490
|
+
it "removes the first has one document from the identity map" do
|
2491
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_one.id]).to be_nil
|
2492
|
+
end
|
2493
|
+
|
2494
|
+
it "inserts the second has one document into the identity map" do
|
2495
|
+
expect(Mongoid::IdentityMap[Game.collection_name][game_two.id]).to eq(game_two)
|
2496
|
+
end
|
2497
|
+
end
|
2498
|
+
end
|
2499
|
+
|
2500
|
+
describe "#inclusions" do
|
2501
|
+
|
2502
|
+
let(:criteria) do
|
2503
|
+
Band.includes(:records)
|
2504
|
+
end
|
2505
|
+
|
2506
|
+
let(:metadata) do
|
2507
|
+
Band.relations["records"]
|
2508
|
+
end
|
2509
|
+
|
2510
|
+
it "returns the inclusions" do
|
2511
|
+
expect(criteria.inclusions).to eq([ metadata ])
|
2512
|
+
end
|
2513
|
+
end
|
2514
|
+
|
2515
|
+
describe "#inclusions=" do
|
2516
|
+
|
2517
|
+
let(:criteria) do
|
2518
|
+
Band.all
|
2519
|
+
end
|
2520
|
+
|
2521
|
+
let(:metadata) do
|
2522
|
+
Band.relations["records"]
|
2523
|
+
end
|
2524
|
+
|
2525
|
+
before do
|
2526
|
+
criteria.inclusions = [ metadata ]
|
2527
|
+
end
|
2528
|
+
|
2529
|
+
it "sets the inclusions" do
|
2530
|
+
expect(criteria.inclusions).to eq([ metadata ])
|
2531
|
+
end
|
2532
|
+
end
|
2533
|
+
|
2534
|
+
describe "#lt" do
|
2535
|
+
|
2536
|
+
let!(:match) do
|
2537
|
+
Band.create(member_count: 1)
|
2538
|
+
end
|
2539
|
+
|
2540
|
+
let!(:non_match) do
|
2541
|
+
Band.create(member_count: 5)
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
let(:criteria) do
|
2545
|
+
Band.lt(member_count: 4)
|
2546
|
+
end
|
2547
|
+
|
2548
|
+
it "returns the matching documents" do
|
2549
|
+
expect(criteria).to eq([ match ])
|
2550
|
+
end
|
2551
|
+
end
|
2552
|
+
|
2553
|
+
describe "#lte" do
|
2554
|
+
|
2555
|
+
let!(:match) do
|
2556
|
+
Band.create(member_count: 4)
|
2557
|
+
end
|
2558
|
+
|
2559
|
+
let!(:non_match) do
|
2560
|
+
Band.create(member_count: 5)
|
2561
|
+
end
|
2562
|
+
|
2563
|
+
let(:criteria) do
|
2564
|
+
Band.lte(member_count: 4)
|
2565
|
+
end
|
2566
|
+
|
2567
|
+
it "returns the matching documents" do
|
2568
|
+
expect(criteria).to eq([ match ])
|
2569
|
+
end
|
2570
|
+
end
|
2571
|
+
|
2572
|
+
describe "#map_reduce" do
|
2573
|
+
|
2574
|
+
let(:map) do
|
2575
|
+
%Q{
|
2576
|
+
function() {
|
2577
|
+
emit(this.name, { likes: this.likes });
|
2578
|
+
}}
|
2579
|
+
end
|
2580
|
+
|
2581
|
+
let(:reduce) do
|
2582
|
+
%Q{
|
2583
|
+
function(key, values) {
|
2584
|
+
var result = { likes: 0 };
|
2585
|
+
values.forEach(function(value) {
|
2586
|
+
result.likes += value.likes;
|
2587
|
+
});
|
2588
|
+
return result;
|
2589
|
+
}}
|
2590
|
+
end
|
2591
|
+
|
2592
|
+
let!(:depeche_mode) do
|
2593
|
+
Band.create(name: "Depeche Mode", likes: 200)
|
2594
|
+
end
|
2595
|
+
|
2596
|
+
let!(:tool) do
|
2597
|
+
Band.create(name: "Tool", likes: 100)
|
2598
|
+
end
|
2599
|
+
|
2600
|
+
let(:map_reduce) do
|
2601
|
+
Band.limit(2).map_reduce(map, reduce).out(inline: 1)
|
2602
|
+
end
|
2603
|
+
|
2604
|
+
it "returns the map/reduce results" do
|
2605
|
+
expect(map_reduce).to eq([
|
2606
|
+
{ "_id" => "Depeche Mode", "value" => { "likes" => 200 }},
|
2607
|
+
{ "_id" => "Tool", "value" => { "likes" => 100 }}
|
2608
|
+
])
|
2609
|
+
end
|
2610
|
+
end
|
2611
|
+
|
2612
|
+
describe "#max" do
|
2613
|
+
|
2614
|
+
context "when provided a single field" do
|
2615
|
+
|
2616
|
+
let!(:depeche) do
|
2617
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
2618
|
+
end
|
2619
|
+
|
2620
|
+
let!(:tool) do
|
2621
|
+
Band.create(name: "Tool", likes: 500)
|
2622
|
+
end
|
2623
|
+
|
2624
|
+
let(:criteria) do
|
2625
|
+
Band.all
|
2626
|
+
end
|
2627
|
+
|
2628
|
+
context "when provided a symbol" do
|
2629
|
+
|
2630
|
+
let(:max) do
|
2631
|
+
criteria.max(:likes)
|
2632
|
+
end
|
2633
|
+
|
2634
|
+
it "returns the max of the provided field" do
|
2635
|
+
expect(max).to eq(1000)
|
2636
|
+
end
|
2637
|
+
end
|
2638
|
+
|
2639
|
+
context "when provided a block" do
|
2640
|
+
|
2641
|
+
let(:max) do
|
2642
|
+
criteria.max do |a, b|
|
2643
|
+
a.likes <=> b.likes
|
2644
|
+
end
|
2645
|
+
end
|
2646
|
+
|
2647
|
+
it "returns the document with the max value for the field" do
|
2648
|
+
expect(max).to eq(depeche)
|
2649
|
+
end
|
2650
|
+
end
|
2651
|
+
end
|
2652
|
+
end
|
2653
|
+
|
2654
|
+
describe "#max_distance" do
|
2655
|
+
|
2656
|
+
before do
|
2657
|
+
Bar.create_indexes
|
2658
|
+
end
|
2659
|
+
|
2660
|
+
let!(:match) do
|
2661
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
2662
|
+
end
|
2663
|
+
|
2664
|
+
let!(:non_match) do
|
2665
|
+
Bar.create(location: [ 19.26, 99.70 ])
|
2666
|
+
end
|
2667
|
+
|
2668
|
+
let(:criteria) do
|
2669
|
+
Bar.near(location: [ 52, 13 ]).max_distance(location: 5)
|
2670
|
+
end
|
2671
|
+
|
2672
|
+
it "returns the matching documents" do
|
2673
|
+
expect(criteria).to eq([ match ])
|
2674
|
+
end
|
2675
|
+
end
|
2676
|
+
|
2677
|
+
describe "#merge" do
|
2678
|
+
|
2679
|
+
let(:band) do
|
2680
|
+
Band.new
|
2681
|
+
end
|
2682
|
+
|
2683
|
+
let(:criteria) do
|
2684
|
+
Band.scoped.where(name: "Depeche Mode").asc(:name)
|
2685
|
+
end
|
2686
|
+
|
2687
|
+
context "when merging with another criteria" do
|
2688
|
+
|
2689
|
+
let(:mergeable) do
|
2690
|
+
Band.includes(:records).tap do |crit|
|
2691
|
+
crit.documents = [ band ]
|
2692
|
+
end
|
2693
|
+
end
|
2694
|
+
|
2695
|
+
let(:metadata) do
|
2696
|
+
Band.relations["records"]
|
2697
|
+
end
|
2698
|
+
|
2699
|
+
let(:merged) do
|
2700
|
+
criteria.merge(mergeable)
|
2701
|
+
end
|
2702
|
+
|
2703
|
+
it "merges the selector" do
|
2704
|
+
expect(merged.selector).to eq({ "name" => "Depeche Mode" })
|
2705
|
+
end
|
2706
|
+
|
2707
|
+
it "merges the options" do
|
2708
|
+
expect(merged.options).to eq({ sort: { "name" => 1 }})
|
2709
|
+
end
|
2710
|
+
|
2711
|
+
it "merges the documents" do
|
2712
|
+
expect(merged.documents).to eq([ band ])
|
2713
|
+
end
|
2714
|
+
|
2715
|
+
it "merges the scoping options" do
|
2716
|
+
expect(merged.scoping_options).to eq([ nil, nil ])
|
2717
|
+
end
|
2718
|
+
|
2719
|
+
it "merges the inclusions" do
|
2720
|
+
expect(merged.inclusions).to eq([ metadata ])
|
2721
|
+
end
|
2722
|
+
|
2723
|
+
it "returns a new criteria" do
|
2724
|
+
expect(merged).to_not equal(criteria)
|
2725
|
+
end
|
2726
|
+
end
|
2727
|
+
|
2728
|
+
context "when merging with a hash" do
|
2729
|
+
|
2730
|
+
let(:mergeable) do
|
2731
|
+
{ klass: Band, includes: [ :records ] }
|
2732
|
+
end
|
2733
|
+
|
2734
|
+
let(:metadata) do
|
2735
|
+
Band.relations["records"]
|
2736
|
+
end
|
2737
|
+
|
2738
|
+
let(:merged) do
|
2739
|
+
criteria.merge(mergeable)
|
2740
|
+
end
|
2741
|
+
|
2742
|
+
it "merges the selector" do
|
2743
|
+
expect(merged.selector).to eq({ "name" => "Depeche Mode" })
|
2744
|
+
end
|
2745
|
+
|
2746
|
+
it "merges the options" do
|
2747
|
+
expect(merged.options).to eq({ sort: { "name" => 1 }})
|
2748
|
+
end
|
2749
|
+
|
2750
|
+
it "merges the scoping options" do
|
2751
|
+
expect(merged.scoping_options).to eq([ nil, nil ])
|
2752
|
+
end
|
2753
|
+
|
2754
|
+
it "merges the inclusions" do
|
2755
|
+
expect(merged.inclusions).to eq([ metadata ])
|
2756
|
+
end
|
2757
|
+
|
2758
|
+
it "returns a new criteria" do
|
2759
|
+
expect(merged).to_not equal(criteria)
|
2760
|
+
end
|
2761
|
+
end
|
2762
|
+
end
|
2763
|
+
|
2764
|
+
describe "#merge!" do
|
2765
|
+
|
2766
|
+
let(:band) do
|
2767
|
+
Band.new
|
2768
|
+
end
|
2769
|
+
|
2770
|
+
let(:criteria) do
|
2771
|
+
Band.scoped.where(name: "Depeche Mode").asc(:name)
|
2772
|
+
end
|
2773
|
+
|
2774
|
+
let(:mergeable) do
|
2775
|
+
Band.includes(:records).tap do |crit|
|
2776
|
+
crit.documents = [ band ]
|
2777
|
+
end
|
2778
|
+
end
|
2779
|
+
|
2780
|
+
let(:metadata) do
|
2781
|
+
Band.relations["records"]
|
2782
|
+
end
|
2783
|
+
|
2784
|
+
let(:merged) do
|
2785
|
+
criteria.merge!(mergeable)
|
2786
|
+
end
|
2787
|
+
|
2788
|
+
it "merges the selector" do
|
2789
|
+
expect(merged.selector).to eq({ "name" => "Depeche Mode" })
|
2790
|
+
end
|
2791
|
+
|
2792
|
+
it "merges the options" do
|
2793
|
+
expect(merged.options).to eq({ sort: { "name" => 1 }})
|
2794
|
+
end
|
2795
|
+
|
2796
|
+
it "merges the documents" do
|
2797
|
+
expect(merged.documents).to eq([ band ])
|
2798
|
+
end
|
2799
|
+
|
2800
|
+
it "merges the scoping options" do
|
2801
|
+
expect(merged.scoping_options).to eq([ nil, nil ])
|
2802
|
+
end
|
2803
|
+
|
2804
|
+
it "merges the inclusions" do
|
2805
|
+
expect(merged.inclusions).to eq([ metadata ])
|
2806
|
+
end
|
2807
|
+
|
2808
|
+
it "returns the same criteria" do
|
2809
|
+
expect(merged).to equal(criteria)
|
2810
|
+
end
|
2811
|
+
end
|
2812
|
+
|
2813
|
+
describe "#min" do
|
2814
|
+
|
2815
|
+
context "when provided a single field" do
|
2816
|
+
|
2817
|
+
let!(:depeche) do
|
2818
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
2819
|
+
end
|
2820
|
+
|
2821
|
+
let!(:tool) do
|
2822
|
+
Band.create(name: "Tool", likes: 500)
|
2823
|
+
end
|
2824
|
+
|
2825
|
+
let(:criteria) do
|
2826
|
+
Band.all
|
2827
|
+
end
|
2828
|
+
|
2829
|
+
context "when provided a symbol" do
|
2830
|
+
|
2831
|
+
let(:min) do
|
2832
|
+
criteria.min(:likes)
|
2833
|
+
end
|
2834
|
+
|
2835
|
+
it "returns the min of the provided field" do
|
2836
|
+
expect(min).to eq(500)
|
2837
|
+
end
|
2838
|
+
end
|
2839
|
+
|
2840
|
+
context "when provided a block" do
|
2841
|
+
|
2842
|
+
let(:min) do
|
2843
|
+
criteria.min do |a, b|
|
2844
|
+
a.likes <=> b.likes
|
2845
|
+
end
|
2846
|
+
end
|
2847
|
+
|
2848
|
+
it "returns the document with the min value for the field" do
|
2849
|
+
expect(min).to eq(tool)
|
2850
|
+
end
|
2851
|
+
end
|
2852
|
+
end
|
2853
|
+
end
|
2854
|
+
|
2855
|
+
describe "#mod" do
|
2856
|
+
|
2857
|
+
let!(:match) do
|
2858
|
+
Band.create(member_count: 5)
|
2859
|
+
end
|
2860
|
+
|
2861
|
+
let!(:non_match) do
|
2862
|
+
Band.create(member_count: 2)
|
2863
|
+
end
|
2864
|
+
|
2865
|
+
let(:criteria) do
|
2866
|
+
Band.mod(member_count: [ 4, 1 ])
|
2867
|
+
end
|
2868
|
+
|
2869
|
+
it "returns the matching documents" do
|
2870
|
+
expect(criteria).to eq([ match ])
|
2871
|
+
end
|
2872
|
+
end
|
2873
|
+
|
2874
|
+
describe "#ne" do
|
2875
|
+
|
2876
|
+
let!(:match) do
|
2877
|
+
Band.create(name: "Depeche Mode")
|
2878
|
+
end
|
2879
|
+
|
2880
|
+
let!(:non_match) do
|
2881
|
+
Band.create(name: "Tool")
|
2882
|
+
end
|
2883
|
+
|
2884
|
+
let(:criteria) do
|
2885
|
+
Band.ne(name: "Tool")
|
2886
|
+
end
|
2887
|
+
|
2888
|
+
it "returns the matching documents" do
|
2889
|
+
expect(criteria).to eq([ match ])
|
2890
|
+
end
|
2891
|
+
end
|
2892
|
+
|
2893
|
+
describe "#near" do
|
2894
|
+
|
2895
|
+
before do
|
2896
|
+
Bar.create_indexes
|
2897
|
+
end
|
2898
|
+
|
2899
|
+
let!(:match) do
|
2900
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
2901
|
+
end
|
2902
|
+
|
2903
|
+
let(:criteria) do
|
2904
|
+
Bar.near(location: [ 52, 13 ])
|
2905
|
+
end
|
2906
|
+
|
2907
|
+
it "returns the matching documents" do
|
2908
|
+
expect(criteria).to eq([ match ])
|
2909
|
+
end
|
2910
|
+
end
|
2911
|
+
|
2912
|
+
describe "#near_sphere" do
|
2913
|
+
|
2914
|
+
before do
|
2915
|
+
Bar.create_indexes
|
2916
|
+
end
|
2917
|
+
|
2918
|
+
let!(:match) do
|
2919
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
2920
|
+
end
|
2921
|
+
|
2922
|
+
let(:criteria) do
|
2923
|
+
Bar.near_sphere(location: [ 52, 13 ])
|
2924
|
+
end
|
2925
|
+
|
2926
|
+
it "returns the matching documents" do
|
2927
|
+
expect(criteria).to eq([ match ])
|
2928
|
+
end
|
2929
|
+
end
|
2930
|
+
|
2931
|
+
describe "#nin" do
|
2932
|
+
|
2933
|
+
let!(:match) do
|
2934
|
+
Band.create(name: "Depeche Mode")
|
2935
|
+
end
|
2936
|
+
|
2937
|
+
let!(:non_match) do
|
2938
|
+
Band.create(name: "Tool")
|
2939
|
+
end
|
2940
|
+
|
2941
|
+
let(:criteria) do
|
2942
|
+
Band.nin(name: [ "Tool" ])
|
2943
|
+
end
|
2944
|
+
|
2945
|
+
it "returns the matching documents" do
|
2946
|
+
expect(criteria).to eq([ match ])
|
2947
|
+
end
|
2948
|
+
end
|
2949
|
+
|
2950
|
+
describe "#nor" do
|
2951
|
+
|
2952
|
+
let!(:match) do
|
2953
|
+
Band.create(name: "Depeche Mode")
|
2954
|
+
end
|
2955
|
+
|
2956
|
+
let!(:non_match) do
|
2957
|
+
Band.create(name: "Tool")
|
2958
|
+
end
|
2959
|
+
|
2960
|
+
let(:criteria) do
|
2961
|
+
Band.nor({ name: "Tool" }, { name: "New Order" })
|
2962
|
+
end
|
2963
|
+
|
2964
|
+
it "returns the matching documents" do
|
2965
|
+
expect(criteria).to eq([ match ])
|
2966
|
+
end
|
2967
|
+
end
|
2968
|
+
|
2969
|
+
describe "#only" do
|
2970
|
+
|
2971
|
+
let!(:band) do
|
2972
|
+
Band.create(name: "Depeche Mode", likes: 3, views: 10)
|
2973
|
+
end
|
2974
|
+
|
2975
|
+
context "when not using inheritance" do
|
2976
|
+
|
2977
|
+
context "when passing splat args" do
|
2978
|
+
|
2979
|
+
let(:criteria) do
|
2980
|
+
Band.only(:_id)
|
2981
|
+
end
|
2982
|
+
|
2983
|
+
it "limits the returned fields" do
|
2984
|
+
expect(criteria.first.name).to be_nil
|
2985
|
+
end
|
2986
|
+
|
2987
|
+
it "does not add _type to the fields" do
|
2988
|
+
expect(criteria.options[:fields]["_type"]).to be_nil
|
2989
|
+
end
|
2990
|
+
end
|
2991
|
+
|
2992
|
+
context "when passing an array" do
|
2993
|
+
|
2994
|
+
let(:criteria) do
|
2995
|
+
Band.only([ :name, :likes ])
|
2996
|
+
end
|
2997
|
+
|
2998
|
+
it "includes the limited fields" do
|
2999
|
+
expect(criteria.first.name).to_not be_nil
|
3000
|
+
end
|
3001
|
+
|
3002
|
+
it "excludes the non included fields" do
|
3003
|
+
expect(criteria.first.active).to be_nil
|
3004
|
+
end
|
3005
|
+
|
3006
|
+
it "does not add _type to the fields" do
|
3007
|
+
expect(criteria.options[:fields]["_type"]).to be_nil
|
3008
|
+
end
|
3009
|
+
end
|
3010
|
+
|
3011
|
+
context "when instantiating a class of another type inside the iteration" do
|
3012
|
+
|
3013
|
+
let(:criteria) do
|
3014
|
+
Band.only(:name)
|
3015
|
+
end
|
3016
|
+
|
3017
|
+
it "only limits the fields on the correct model" do
|
3018
|
+
criteria.each do |band|
|
3019
|
+
expect(Person.new.age).to eq(100)
|
3020
|
+
end
|
3021
|
+
end
|
3022
|
+
end
|
3023
|
+
|
3024
|
+
context "when instantiating a document not in the result set" do
|
3025
|
+
|
3026
|
+
let(:criteria) do
|
3027
|
+
Band.only(:name)
|
3028
|
+
end
|
3029
|
+
|
3030
|
+
it "only limits the fields on the correct criteria" do
|
3031
|
+
criteria.each do |band|
|
3032
|
+
expect(Band.new.active).to be_true
|
3033
|
+
end
|
3034
|
+
end
|
3035
|
+
end
|
3036
|
+
|
3037
|
+
context "when nesting a criteria within a criteria" do
|
3038
|
+
|
3039
|
+
let(:criteria) do
|
3040
|
+
Band.only(:name)
|
3041
|
+
end
|
3042
|
+
|
3043
|
+
it "only limits the fields on the correct criteria" do
|
3044
|
+
criteria.each do |band|
|
3045
|
+
Band.all.each do |b|
|
3046
|
+
expect(b.active).to be_true
|
3047
|
+
end
|
3048
|
+
end
|
3049
|
+
end
|
3050
|
+
end
|
3051
|
+
end
|
3052
|
+
|
3053
|
+
context "when using inheritance" do
|
3054
|
+
|
3055
|
+
let(:criteria) do
|
3056
|
+
Doctor.only(:_id)
|
3057
|
+
end
|
3058
|
+
|
3059
|
+
it "adds _type to the fields" do
|
3060
|
+
expect(criteria.options[:fields]["_type"]).to eq(1)
|
3061
|
+
end
|
3062
|
+
end
|
3063
|
+
|
3064
|
+
context "when limiting to embedded documents" do
|
3065
|
+
|
3066
|
+
context "when the embedded documents are aliased" do
|
3067
|
+
|
3068
|
+
let(:criteria) do
|
3069
|
+
Person.only(:phones)
|
3070
|
+
end
|
3071
|
+
|
3072
|
+
it "properly uses the database field name" do
|
3073
|
+
expect(criteria.options).to eq(fields: { "mobile_phones" => 1 })
|
3074
|
+
end
|
3075
|
+
end
|
3076
|
+
end
|
3077
|
+
end
|
3078
|
+
|
3079
|
+
[ :or, :any_of ].each do |method|
|
3080
|
+
|
3081
|
+
describe "\##{method}" do
|
3082
|
+
|
3083
|
+
let!(:match) do
|
3084
|
+
Band.create(name: "Depeche Mode")
|
3085
|
+
end
|
3086
|
+
|
3087
|
+
let!(:non_match) do
|
3088
|
+
Band.create(name: "Tool")
|
3089
|
+
end
|
3090
|
+
|
3091
|
+
context "when sending a normal $or criterion" do
|
3092
|
+
|
3093
|
+
let(:criteria) do
|
3094
|
+
Band.send(method, { name: "Depeche Mode" }, { name: "New Order" })
|
3095
|
+
end
|
3096
|
+
|
3097
|
+
it "returns the matching documents" do
|
3098
|
+
expect(criteria).to eq([ match ])
|
3099
|
+
end
|
3100
|
+
end
|
3101
|
+
|
3102
|
+
context "when matching against an id or other parameter" do
|
3103
|
+
|
3104
|
+
let(:criteria) do
|
3105
|
+
Band.send(method, { id: match.id }, { name: "New Order" })
|
3106
|
+
end
|
3107
|
+
|
3108
|
+
it "returns the matching documents" do
|
3109
|
+
expect(criteria).to eq([ match ])
|
3110
|
+
end
|
3111
|
+
end
|
3112
|
+
end
|
3113
|
+
end
|
3114
|
+
|
3115
|
+
describe "#pluck" do
|
3116
|
+
|
3117
|
+
let!(:depeche) do
|
3118
|
+
Band.create(name: "Depeche Mode", likes: 3)
|
3119
|
+
end
|
3120
|
+
|
3121
|
+
let!(:tool) do
|
3122
|
+
Band.create(name: "Tool", likes: 3)
|
3123
|
+
end
|
3124
|
+
|
3125
|
+
let!(:photek) do
|
3126
|
+
Band.create(name: "Photek", likes: 1)
|
3127
|
+
end
|
3128
|
+
|
3129
|
+
context "when the criteria matches" do
|
3130
|
+
|
3131
|
+
context "when there are no duplicate values" do
|
3132
|
+
|
3133
|
+
let(:criteria) do
|
3134
|
+
Band.where(:name.exists => true)
|
3135
|
+
end
|
3136
|
+
|
3137
|
+
let!(:plucked) do
|
3138
|
+
criteria.pluck(:name)
|
3139
|
+
end
|
3140
|
+
|
3141
|
+
it "returns the values" do
|
3142
|
+
expect(plucked).to eq([ "Depeche Mode", "Tool", "Photek" ])
|
3143
|
+
end
|
3144
|
+
|
3145
|
+
context "when subsequently executing the criteria without a pluck" do
|
3146
|
+
|
3147
|
+
it "does not limit the fields" do
|
3148
|
+
expect(criteria.first.likes).to eq(3)
|
3149
|
+
end
|
3150
|
+
end
|
3151
|
+
end
|
3152
|
+
|
3153
|
+
context "when plucking mult-fields" do
|
3154
|
+
|
3155
|
+
let(:plucked) do
|
3156
|
+
Band.where(:name.exists => true).pluck(:name, :likes)
|
3157
|
+
end
|
3158
|
+
|
3159
|
+
it "returns the values" do
|
3160
|
+
expect(plucked).to eq([ ["Depeche Mode", 3], ["Tool", 3], ["Photek", 1] ])
|
3161
|
+
end
|
3162
|
+
end
|
3163
|
+
|
3164
|
+
context "when there are duplicate values" do
|
3165
|
+
|
3166
|
+
let(:plucked) do
|
3167
|
+
Band.where(:name.exists => true).pluck(:likes)
|
3168
|
+
end
|
3169
|
+
|
3170
|
+
it "returns the duplicates" do
|
3171
|
+
expect(plucked).to eq([ 3, 3, 1 ])
|
3172
|
+
end
|
3173
|
+
end
|
3174
|
+
end
|
3175
|
+
|
3176
|
+
context "when the criteria does not match" do
|
3177
|
+
|
3178
|
+
let(:plucked) do
|
3179
|
+
Band.where(name: "New Order").pluck(:_id)
|
3180
|
+
end
|
3181
|
+
|
3182
|
+
it "returns an empty array" do
|
3183
|
+
expect(plucked).to be_empty
|
3184
|
+
end
|
3185
|
+
end
|
3186
|
+
|
3187
|
+
context "when plucking an aliased field" do
|
3188
|
+
|
3189
|
+
let(:plucked) do
|
3190
|
+
Band.all.pluck(:id)
|
3191
|
+
end
|
3192
|
+
|
3193
|
+
it "returns the field values" do
|
3194
|
+
expect(plucked).to eq([ depeche.id, tool.id, photek.id ])
|
3195
|
+
end
|
3196
|
+
end
|
3197
|
+
|
3198
|
+
context "when plucking a field that doesnt exist" do
|
3199
|
+
|
3200
|
+
context "when pluck one field" do
|
3201
|
+
|
3202
|
+
let(:plucked) do
|
3203
|
+
Band.all.pluck(:foo)
|
3204
|
+
end
|
3205
|
+
|
3206
|
+
it "returns a empty array" do
|
3207
|
+
expect(plucked).to eq([])
|
3208
|
+
end
|
3209
|
+
end
|
3210
|
+
|
3211
|
+
context "when pluck multiple fields" do
|
3212
|
+
|
3213
|
+
let(:plucked) do
|
3214
|
+
Band.all.pluck(:foo, :bar)
|
3215
|
+
end
|
3216
|
+
|
3217
|
+
it "returns a empty array" do
|
3218
|
+
expect(plucked).to eq([[], [], []])
|
3219
|
+
end
|
3220
|
+
end
|
3221
|
+
end
|
3222
|
+
end
|
3223
|
+
|
3224
|
+
describe "#respond_to?" do
|
3225
|
+
|
3226
|
+
let(:criteria) do
|
3227
|
+
described_class.new(Person)
|
3228
|
+
end
|
3229
|
+
|
3230
|
+
before do
|
3231
|
+
class Person
|
3232
|
+
def self.ages; self; end
|
3233
|
+
end
|
3234
|
+
end
|
3235
|
+
|
3236
|
+
context "when asking about a model public class method" do
|
3237
|
+
|
3238
|
+
it "returns true" do
|
3239
|
+
expect(criteria).to respond_to(:ages)
|
3240
|
+
end
|
3241
|
+
end
|
3242
|
+
|
3243
|
+
context "when asking about a model private class method" do
|
3244
|
+
|
3245
|
+
context "when including private methods" do
|
3246
|
+
|
3247
|
+
it "returns true" do
|
3248
|
+
expect(criteria.respond_to?(:for_ids, true)).to be_true
|
3249
|
+
end
|
3250
|
+
end
|
3251
|
+
end
|
3252
|
+
|
3253
|
+
context "when asking about a model class public instance method" do
|
3254
|
+
|
3255
|
+
it "returns true" do
|
3256
|
+
expect(criteria.respond_to?(:join)).to be_true
|
3257
|
+
end
|
3258
|
+
end
|
3259
|
+
|
3260
|
+
context "when asking about a model private instance method" do
|
3261
|
+
|
3262
|
+
context "when not including private methods" do
|
3263
|
+
|
3264
|
+
it "returns false" do
|
3265
|
+
expect(criteria).to_not respond_to(:fork)
|
3266
|
+
end
|
3267
|
+
end
|
3268
|
+
|
3269
|
+
context "when including private methods" do
|
3270
|
+
|
3271
|
+
it "returns true" do
|
3272
|
+
expect(criteria.respond_to?(:fork, true)).to be_true
|
3273
|
+
end
|
3274
|
+
end
|
3275
|
+
end
|
3276
|
+
|
3277
|
+
context "when asking about a criteria instance method" do
|
3278
|
+
|
3279
|
+
it "returns true" do
|
3280
|
+
expect(criteria).to respond_to(:context)
|
3281
|
+
end
|
3282
|
+
end
|
3283
|
+
|
3284
|
+
context "when asking about a private criteria instance method" do
|
3285
|
+
|
3286
|
+
context "when not including private methods" do
|
3287
|
+
|
3288
|
+
it "returns false" do
|
3289
|
+
expect(criteria).to_not respond_to(:puts)
|
3290
|
+
end
|
3291
|
+
end
|
3292
|
+
|
3293
|
+
context "when including private methods" do
|
3294
|
+
|
3295
|
+
it "returns true" do
|
3296
|
+
expect(criteria.respond_to?(:puts, true)).to be_true
|
3297
|
+
end
|
3298
|
+
end
|
3299
|
+
end
|
3300
|
+
end
|
3301
|
+
|
3302
|
+
describe "#sort" do
|
3303
|
+
|
3304
|
+
let!(:depeche) do
|
3305
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
3306
|
+
end
|
3307
|
+
|
3308
|
+
let!(:tool) do
|
3309
|
+
Band.create(name: "Tool", likes: 500)
|
3310
|
+
end
|
3311
|
+
|
3312
|
+
let(:sorted) do
|
3313
|
+
Band.all.sort do |a, b|
|
3314
|
+
b.name <=> a.name
|
3315
|
+
end
|
3316
|
+
end
|
3317
|
+
|
3318
|
+
it "sorts the results in memory" do
|
3319
|
+
expect(sorted).to eq([ tool, depeche ])
|
3320
|
+
end
|
3321
|
+
end
|
3322
|
+
|
3323
|
+
describe "#sum" do
|
3324
|
+
|
3325
|
+
context "when provided a single field" do
|
3326
|
+
|
3327
|
+
let!(:depeche) do
|
3328
|
+
Band.create(name: "Depeche Mode", likes: 1000)
|
3329
|
+
end
|
3330
|
+
|
3331
|
+
let!(:tool) do
|
3332
|
+
Band.create(name: "Tool", likes: 500)
|
3333
|
+
end
|
3334
|
+
|
3335
|
+
let(:criteria) do
|
3336
|
+
Band.all
|
3337
|
+
end
|
3338
|
+
|
3339
|
+
context "when provided a symbol" do
|
3340
|
+
|
3341
|
+
let(:sum) do
|
3342
|
+
criteria.sum(:likes)
|
3343
|
+
end
|
3344
|
+
|
3345
|
+
it "returns the sum of the provided field" do
|
3346
|
+
expect(sum).to eq(1500)
|
3347
|
+
end
|
3348
|
+
end
|
3349
|
+
|
3350
|
+
context "when provided a block" do
|
3351
|
+
|
3352
|
+
let(:sum) do
|
3353
|
+
criteria.sum(&:likes)
|
3354
|
+
end
|
3355
|
+
|
3356
|
+
it "returns the sum for the provided block" do
|
3357
|
+
expect(sum).to eq(1500)
|
3358
|
+
end
|
3359
|
+
end
|
3360
|
+
end
|
3361
|
+
end
|
3362
|
+
|
3363
|
+
describe "#to_ary" do
|
3364
|
+
|
3365
|
+
let!(:band) do
|
3366
|
+
Band.create(name: "Depeche Mode")
|
3367
|
+
end
|
3368
|
+
|
3369
|
+
let(:criteria) do
|
3370
|
+
Band.where(name: "Depeche Mode")
|
3371
|
+
end
|
3372
|
+
|
3373
|
+
it "returns the executed criteria" do
|
3374
|
+
expect(criteria.to_ary).to eq([ band ])
|
3375
|
+
end
|
3376
|
+
end
|
3377
|
+
|
3378
|
+
describe "#extras with a hint" do
|
3379
|
+
|
3380
|
+
let!(:band) do
|
3381
|
+
Band.create(name: "Depeche Mode")
|
3382
|
+
end
|
3383
|
+
|
3384
|
+
let(:criteria) do
|
3385
|
+
Band.where(name: "Depeche Mode").extras(:hint => {:bad_hint => 1})
|
3386
|
+
end
|
3387
|
+
|
3388
|
+
it "executes the criteria while properly giving the hint to Mongo" do
|
3389
|
+
expect { criteria.to_ary }.to raise_error(Moped::Errors::QueryFailure, %r{failed with error 10113: "bad hint"})
|
3390
|
+
end
|
3391
|
+
end
|
3392
|
+
|
3393
|
+
describe "#hint" do
|
3394
|
+
|
3395
|
+
let!(:band) do
|
3396
|
+
Band.create(name: "Depeche Mode")
|
3397
|
+
end
|
3398
|
+
|
3399
|
+
let(:criteria) do
|
3400
|
+
Band.where(name: "Depeche Mode").hint(bad_hint: 1)
|
3401
|
+
end
|
3402
|
+
|
3403
|
+
it "executes the criteria while properly giving the hint to Mongo" do
|
3404
|
+
expect { criteria.to_ary }.to raise_error(Moped::Errors::QueryFailure, %r{failed with error 10113: "bad hint"})
|
3405
|
+
end
|
3406
|
+
end
|
3407
|
+
|
3408
|
+
describe "#max_scan" do
|
3409
|
+
let!(:band) do
|
3410
|
+
Band.create(name: "Depeche Mode")
|
3411
|
+
end
|
3412
|
+
|
3413
|
+
let!(:band2) do
|
3414
|
+
Band.create(name: "Tool")
|
3415
|
+
end
|
3416
|
+
|
3417
|
+
let(:criteria) do
|
3418
|
+
Band.where({}).max_scan(1)
|
3419
|
+
end
|
3420
|
+
|
3421
|
+
it "executes the criteria while properly giving the max scan to Mongo" do
|
3422
|
+
expect(criteria.to_ary).to eq [band]
|
3423
|
+
end
|
3424
|
+
end
|
3425
|
+
|
3426
|
+
describe "#text_search" do
|
3427
|
+
|
3428
|
+
let(:criteria) do
|
3429
|
+
Word.all
|
3430
|
+
end
|
3431
|
+
|
3432
|
+
before do
|
3433
|
+
Word.with(database: "admin").mongo_session.command(setParameter: 1, textSearchEnabled: true)
|
3434
|
+
Word.create_indexes
|
3435
|
+
Word.with(safe: true).create!(name: "phase", origin: "latin")
|
3436
|
+
end
|
3437
|
+
|
3438
|
+
after(:all) do
|
3439
|
+
Word.remove_indexes
|
3440
|
+
end
|
3441
|
+
|
3442
|
+
let(:search) do
|
3443
|
+
criteria.text_search("phase")
|
3444
|
+
end
|
3445
|
+
|
3446
|
+
it "returns all fields" do
|
3447
|
+
expect(search.first.origin).to eq("latin")
|
3448
|
+
end
|
3449
|
+
end
|
3450
|
+
|
3451
|
+
describe "#to_criteria" do
|
3452
|
+
|
3453
|
+
let(:criteria) do
|
3454
|
+
Band.all
|
3455
|
+
end
|
3456
|
+
|
3457
|
+
it "returns self" do
|
3458
|
+
expect(criteria.to_criteria).to eq(criteria)
|
3459
|
+
end
|
3460
|
+
end
|
3461
|
+
|
3462
|
+
describe "#to_proc" do
|
3463
|
+
|
3464
|
+
let(:criteria) do
|
3465
|
+
Band.all
|
3466
|
+
end
|
3467
|
+
|
3468
|
+
it "returns a proc" do
|
3469
|
+
expect(criteria.to_proc).to be_a(Proc)
|
3470
|
+
end
|
3471
|
+
|
3472
|
+
it "wraps the criteria in the proc" do
|
3473
|
+
expect(criteria.to_proc[]).to eq(criteria)
|
3474
|
+
end
|
3475
|
+
end
|
3476
|
+
|
3477
|
+
describe "#type" do
|
3478
|
+
|
3479
|
+
context "when the type is a string" do
|
3480
|
+
|
3481
|
+
let!(:browser) do
|
3482
|
+
Browser.create
|
3483
|
+
end
|
3484
|
+
|
3485
|
+
let(:criteria) do
|
3486
|
+
Canvas.all.type("Browser")
|
3487
|
+
end
|
3488
|
+
|
3489
|
+
it "returns documents with the provided type" do
|
3490
|
+
expect(criteria).to eq([ browser ])
|
3491
|
+
end
|
3492
|
+
end
|
3493
|
+
|
3494
|
+
context "when the type is an Array of type" do
|
3495
|
+
|
3496
|
+
let!(:browser) do
|
3497
|
+
Firefox.create
|
3498
|
+
end
|
3499
|
+
|
3500
|
+
let(:criteria) do
|
3501
|
+
Canvas.all.type([ "Browser", "Firefox" ])
|
3502
|
+
end
|
3503
|
+
|
3504
|
+
it "returns documents with the provided types" do
|
3505
|
+
expect(criteria).to eq([ browser ])
|
3506
|
+
end
|
3507
|
+
end
|
3508
|
+
end
|
3509
|
+
|
3510
|
+
describe "#where" do
|
3511
|
+
|
3512
|
+
let!(:match) do
|
3513
|
+
Band.create(name: "Depeche Mode")
|
3514
|
+
end
|
3515
|
+
|
3516
|
+
let!(:non_match) do
|
3517
|
+
Band.create(name: "Tool")
|
3518
|
+
end
|
3519
|
+
|
3520
|
+
context "when provided a string" do
|
3521
|
+
|
3522
|
+
context "when the criteria is embedded" do
|
3523
|
+
|
3524
|
+
it "raises an error" do
|
3525
|
+
expect {
|
3526
|
+
match.records.where("this.name == null")
|
3527
|
+
}.to raise_error(Mongoid::Errors::UnsupportedJavascript)
|
3528
|
+
end
|
3529
|
+
end
|
3530
|
+
|
3531
|
+
context "when the criteria is not embedded" do
|
3532
|
+
|
3533
|
+
let(:criteria) do
|
3534
|
+
Band.where("this.name == 'Depeche Mode'")
|
3535
|
+
end
|
3536
|
+
|
3537
|
+
it "returns the matching documents" do
|
3538
|
+
expect(criteria).to eq([ match ])
|
3539
|
+
end
|
3540
|
+
end
|
3541
|
+
end
|
3542
|
+
|
3543
|
+
context "when provided criterion" do
|
3544
|
+
|
3545
|
+
context "when the criteria is standard" do
|
3546
|
+
|
3547
|
+
let(:criteria) do
|
3548
|
+
Band.where(name: "Depeche Mode")
|
3549
|
+
end
|
3550
|
+
|
3551
|
+
it "returns the matching documents" do
|
3552
|
+
expect(criteria).to eq([ match ])
|
3553
|
+
end
|
3554
|
+
end
|
3555
|
+
|
3556
|
+
context "when the criteria is an exact fk array match" do
|
3557
|
+
|
3558
|
+
let(:id_one) do
|
3559
|
+
Moped::BSON::ObjectId.new
|
3560
|
+
end
|
3561
|
+
|
3562
|
+
let(:id_two) do
|
3563
|
+
Moped::BSON::ObjectId.new
|
3564
|
+
end
|
3565
|
+
|
3566
|
+
let(:criteria) do
|
3567
|
+
Account.where(agent_ids: [ id_one, id_two ])
|
3568
|
+
end
|
3569
|
+
|
3570
|
+
it "does not wrap the array in another array" do
|
3571
|
+
expect(criteria.selector).to eq({ "agent_ids" => [ id_one, id_two ]})
|
3572
|
+
end
|
3573
|
+
end
|
3574
|
+
end
|
3575
|
+
end
|
3576
|
+
|
3577
|
+
describe "#for_js" do
|
3578
|
+
|
3579
|
+
let!(:match) do
|
3580
|
+
Band.create(name: "Depeche Mode")
|
3581
|
+
end
|
3582
|
+
|
3583
|
+
context "when the code has no scope" do
|
3584
|
+
|
3585
|
+
let(:criteria) do
|
3586
|
+
Band.for_js("this.name == 'Depeche Mode'")
|
3587
|
+
end
|
3588
|
+
|
3589
|
+
it "returns the matching documents" do
|
3590
|
+
expect(criteria).to eq([ match ])
|
3591
|
+
end
|
3592
|
+
end
|
3593
|
+
|
3594
|
+
context "when the code has scope" do
|
3595
|
+
|
3596
|
+
let(:criteria) do
|
3597
|
+
Band.for_js("this.name == param", param: "Depeche Mode")
|
3598
|
+
end
|
3599
|
+
|
3600
|
+
it "returns the matching documents" do
|
3601
|
+
expect(criteria).to eq([ match ])
|
3602
|
+
end
|
3603
|
+
end
|
3604
|
+
end
|
3605
|
+
|
3606
|
+
describe "#method_missing" do
|
3607
|
+
|
3608
|
+
let(:criteria) do
|
3609
|
+
Person.all
|
3610
|
+
end
|
3611
|
+
|
3612
|
+
context "when the method exists on the class" do
|
3613
|
+
|
3614
|
+
before do
|
3615
|
+
Person.should_receive(:minor).and_call_original
|
3616
|
+
end
|
3617
|
+
|
3618
|
+
it "calls the method on the class" do
|
3619
|
+
expect(criteria.minor).to be_empty
|
3620
|
+
end
|
3621
|
+
end
|
3622
|
+
|
3623
|
+
context "when the method exists on the criteria" do
|
3624
|
+
|
3625
|
+
before do
|
3626
|
+
criteria.should_receive(:to_criteria).and_call_original
|
3627
|
+
end
|
3628
|
+
|
3629
|
+
it "calls the method on the criteria" do
|
3630
|
+
expect(criteria.to_criteria).to eq(criteria)
|
3631
|
+
end
|
3632
|
+
end
|
3633
|
+
|
3634
|
+
context "when the method exists on array" do
|
3635
|
+
|
3636
|
+
before do
|
3637
|
+
criteria.should_receive(:entries).and_call_original
|
3638
|
+
end
|
3639
|
+
|
3640
|
+
it "calls the method on the criteria" do
|
3641
|
+
expect(criteria.at(0)).to be_nil
|
3642
|
+
end
|
3643
|
+
end
|
3644
|
+
|
3645
|
+
context "when the method does not exist" do
|
3646
|
+
|
3647
|
+
before do
|
3648
|
+
criteria.should_receive(:entries).never
|
3649
|
+
end
|
3650
|
+
|
3651
|
+
it "raises an error" do
|
3652
|
+
expect {
|
3653
|
+
criteria.to_hash
|
3654
|
+
}.to raise_error(NoMethodError)
|
3655
|
+
end
|
3656
|
+
end
|
3657
|
+
end
|
3658
|
+
|
3659
|
+
describe "#uniq" do
|
3660
|
+
|
3661
|
+
let!(:band_one) do
|
3662
|
+
Band.create(name: "New Order")
|
3663
|
+
end
|
3664
|
+
|
3665
|
+
let!(:band_two) do
|
3666
|
+
Band.create(name: "New Order")
|
3667
|
+
end
|
3668
|
+
|
3669
|
+
let(:criteria) do
|
3670
|
+
Band.all
|
3671
|
+
end
|
3672
|
+
|
3673
|
+
it "passes the block through method_missing" do
|
3674
|
+
expect(criteria.uniq(&:name)).to eq([ band_one ])
|
3675
|
+
end
|
3676
|
+
end
|
3677
|
+
|
3678
|
+
describe "#with" do
|
3679
|
+
|
3680
|
+
let!(:criteria) do
|
3681
|
+
Band.where(name: "Depeche Mode").with(collection: "artists")
|
3682
|
+
end
|
3683
|
+
|
3684
|
+
it "retains the criteria selection" do
|
3685
|
+
expect(criteria.selector).to eq("name" => "Depeche Mode")
|
3686
|
+
end
|
3687
|
+
|
3688
|
+
it "sets the persistence options" do
|
3689
|
+
expect(criteria.persistence_options).to eq(collection: "artists")
|
3690
|
+
end
|
3691
|
+
end
|
3692
|
+
|
3693
|
+
describe "#within_box" do
|
3694
|
+
|
3695
|
+
before do
|
3696
|
+
Bar.create_indexes
|
3697
|
+
end
|
3698
|
+
|
3699
|
+
let!(:match) do
|
3700
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
3701
|
+
end
|
3702
|
+
|
3703
|
+
let(:criteria) do
|
3704
|
+
Bar.within_box(location: [[ 50, 10 ], [ 60, 20 ]])
|
3705
|
+
end
|
3706
|
+
|
3707
|
+
it "returns the matching documents" do
|
3708
|
+
expect(criteria).to eq([ match ])
|
3709
|
+
end
|
3710
|
+
end
|
3711
|
+
|
3712
|
+
describe "#within_circle" do
|
3713
|
+
|
3714
|
+
before do
|
3715
|
+
Bar.create_indexes
|
3716
|
+
end
|
3717
|
+
|
3718
|
+
let!(:match) do
|
3719
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
3720
|
+
end
|
3721
|
+
|
3722
|
+
let(:criteria) do
|
3723
|
+
Bar.within_circle(location: [[ 52, 13 ], 0.5 ])
|
3724
|
+
end
|
3725
|
+
|
3726
|
+
it "returns the matching documents" do
|
3727
|
+
expect(criteria).to eq([ match ])
|
3728
|
+
end
|
3729
|
+
end
|
3730
|
+
|
3731
|
+
describe "#within_polygon" do
|
3732
|
+
|
3733
|
+
before do
|
3734
|
+
Bar.create_indexes
|
3735
|
+
end
|
3736
|
+
|
3737
|
+
let!(:match) do
|
3738
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
3739
|
+
end
|
3740
|
+
|
3741
|
+
let(:criteria) do
|
3742
|
+
Bar.within_polygon(
|
3743
|
+
location: [[ 50, 10 ], [ 50, 20 ], [ 60, 20 ], [ 60, 10 ]]
|
3744
|
+
)
|
3745
|
+
end
|
3746
|
+
|
3747
|
+
it "returns the matching documents" do
|
3748
|
+
expect(criteria).to eq([ match ])
|
3749
|
+
end
|
3750
|
+
end
|
3751
|
+
|
3752
|
+
describe "#within_spherical_circle" do
|
3753
|
+
|
3754
|
+
before do
|
3755
|
+
Bar.create_indexes
|
3756
|
+
end
|
3757
|
+
|
3758
|
+
let!(:match) do
|
3759
|
+
Bar.create(location: [ 52.30, 13.25 ])
|
3760
|
+
end
|
3761
|
+
|
3762
|
+
let(:criteria) do
|
3763
|
+
Bar.within_spherical_circle(location: [[ 52, 13 ], 0.5 ])
|
3764
|
+
end
|
3765
|
+
|
3766
|
+
it "returns the matching documents" do
|
3767
|
+
expect(criteria).to eq([ match ])
|
3768
|
+
end
|
3769
|
+
end
|
3770
|
+
|
3771
|
+
describe "#with_size" do
|
3772
|
+
|
3773
|
+
let!(:match) do
|
3774
|
+
Band.create(genres: [ "electro", "dub" ])
|
3775
|
+
end
|
3776
|
+
|
3777
|
+
let!(:non_match) do
|
3778
|
+
Band.create(genres: [ "house" ])
|
3779
|
+
end
|
3780
|
+
|
3781
|
+
let(:criteria) do
|
3782
|
+
Band.with_size(genres: 2)
|
3783
|
+
end
|
3784
|
+
|
3785
|
+
it "returns the matching documents" do
|
3786
|
+
expect(criteria).to eq([ match ])
|
3787
|
+
end
|
3788
|
+
end
|
3789
|
+
|
3790
|
+
describe "#with_type" do
|
3791
|
+
|
3792
|
+
let!(:match) do
|
3793
|
+
Band.create(name: "Depeche Mode")
|
3794
|
+
end
|
3795
|
+
|
3796
|
+
let(:criteria) do
|
3797
|
+
Band.with_type(name: 2)
|
3798
|
+
end
|
3799
|
+
|
3800
|
+
it "returns the matching documents" do
|
3801
|
+
expect(criteria).to eq([ match ])
|
3802
|
+
end
|
3803
|
+
end
|
3804
|
+
|
3805
|
+
describe "#without" do
|
3806
|
+
|
3807
|
+
context "when omitting to embedded documents" do
|
3808
|
+
|
3809
|
+
context "when the embedded documents are aliased" do
|
3810
|
+
|
3811
|
+
let(:criteria) do
|
3812
|
+
Person.without(:phones)
|
3813
|
+
end
|
3814
|
+
|
3815
|
+
it "properly uses the database field name" do
|
3816
|
+
expect(criteria.options).to eq(fields: { "mobile_phones" => 0 })
|
3817
|
+
end
|
3818
|
+
end
|
3819
|
+
end
|
3820
|
+
end
|
3821
|
+
end
|