mongoid 7.1.2 → 7.2.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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +9 -2
- data/Rakefile +45 -5
- data/lib/config/locales/en.yml +38 -2
- data/lib/mongoid.rb +23 -0
- data/lib/mongoid/association/accessors.rb +37 -2
- data/lib/mongoid/association/depending.rb +1 -6
- data/lib/mongoid/association/many.rb +3 -3
- data/lib/mongoid/association/referenced/belongs_to/binding.rb +1 -1
- data/lib/mongoid/association/referenced/belongs_to/buildable.rb +1 -1
- data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +36 -1
- data/lib/mongoid/association/referenced/has_many/proxy.rb +8 -1
- data/lib/mongoid/association/referenced/has_one/buildable.rb +9 -1
- data/lib/mongoid/association/referenced/has_one/proxy.rb +6 -1
- data/lib/mongoid/atomic/modifiers.rb +1 -1
- data/lib/mongoid/attributes/dynamic.rb +1 -1
- data/lib/mongoid/clients/factory.rb +19 -2
- data/lib/mongoid/clients/options.rb +8 -8
- data/lib/mongoid/clients/sessions.rb +20 -4
- data/lib/mongoid/clients/storage_options.rb +5 -5
- data/lib/mongoid/composable.rb +1 -0
- data/lib/mongoid/config.rb +3 -0
- data/lib/mongoid/contextual/mongo.rb +23 -4
- data/lib/mongoid/copyable.rb +7 -3
- data/lib/mongoid/criteria.rb +57 -7
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +12 -0
- data/lib/mongoid/criteria/queryable/key.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +2 -2
- data/lib/mongoid/criteria/queryable/selectable.rb +21 -6
- data/lib/mongoid/criteria/queryable/selector.rb +3 -3
- data/lib/mongoid/criteria/queryable/storable.rb +3 -3
- data/lib/mongoid/document.rb +15 -3
- data/lib/mongoid/errors.rb +7 -0
- data/lib/mongoid/errors/invalid_discriminator_key_target.rb +25 -0
- data/lib/mongoid/errors/invalid_elem_match_operator.rb +33 -0
- data/lib/mongoid/errors/invalid_estimated_count_criteria.rb +26 -0
- data/lib/mongoid/errors/invalid_expression_operator.rb +28 -0
- data/lib/mongoid/errors/invalid_field_operator.rb +33 -0
- data/lib/mongoid/errors/invalid_query.rb +41 -0
- data/lib/mongoid/errors/no_client_config.rb +2 -2
- data/lib/mongoid/errors/no_default_client.rb +1 -1
- data/lib/mongoid/extensions.rb +1 -0
- data/lib/mongoid/factory.rb +27 -10
- data/lib/mongoid/fields.rb +3 -0
- data/lib/mongoid/fields/validators/macro.rb +26 -10
- data/lib/mongoid/findable.rb +50 -14
- data/lib/mongoid/indexable.rb +2 -2
- data/lib/mongoid/matchable.rb +1 -149
- data/lib/mongoid/matcher.rb +127 -0
- data/lib/mongoid/matcher/all.rb +22 -0
- data/lib/mongoid/matcher/and.rb +21 -0
- data/lib/mongoid/matcher/elem_match.rb +35 -0
- data/lib/mongoid/matcher/elem_match_expression.rb +20 -0
- data/lib/mongoid/matcher/eq.rb +11 -0
- data/lib/mongoid/matcher/eq_impl.rb +32 -0
- data/lib/mongoid/matcher/eq_impl_with_regexp.rb +21 -0
- data/lib/mongoid/matcher/exists.rb +15 -0
- data/lib/mongoid/matcher/expression.rb +40 -0
- data/lib/mongoid/matcher/expression_operator.rb +19 -0
- data/lib/mongoid/matcher/field_expression.rb +63 -0
- data/lib/mongoid/matcher/field_operator.rb +52 -0
- data/lib/mongoid/matcher/gt.rb +17 -0
- data/lib/mongoid/matcher/gte.rb +17 -0
- data/lib/mongoid/matcher/in.rb +25 -0
- data/lib/mongoid/matcher/lt.rb +17 -0
- data/lib/mongoid/matcher/lte.rb +17 -0
- data/lib/mongoid/matcher/ne.rb +16 -0
- data/lib/mongoid/matcher/nin.rb +11 -0
- data/lib/mongoid/matcher/nor.rb +25 -0
- data/lib/mongoid/matcher/not.rb +29 -0
- data/lib/mongoid/matcher/or.rb +21 -0
- data/lib/mongoid/matcher/regex.rb +41 -0
- data/lib/mongoid/matcher/size.rb +26 -0
- data/lib/mongoid/persistable/deletable.rb +1 -1
- data/lib/mongoid/query_cache.rb +81 -37
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/stringified_symbol.rb +53 -0
- data/lib/mongoid/tasks/database.rb +38 -3
- data/lib/mongoid/traversable.rb +111 -4
- data/lib/mongoid/version.rb +1 -1
- data/spec/README.md +19 -4
- data/spec/integration/app_spec.rb +85 -23
- data/spec/integration/associations/embedded_spec.rb +94 -0
- data/spec/integration/associations/embeds_many_spec.rb +24 -0
- data/spec/integration/associations/embeds_one_spec.rb +24 -0
- data/spec/integration/associations/has_many_spec.rb +129 -0
- data/spec/integration/associations/has_one_spec.rb +129 -0
- data/spec/integration/associations/nested_attributes_assignment_spec.rb +116 -0
- data/spec/integration/atomic/modifiers_spec.rb +117 -0
- data/spec/integration/bson_regexp_raw_spec.rb +20 -0
- data/spec/integration/criteria/date_field_spec.rb +41 -0
- data/spec/integration/discriminator_key_spec.rb +354 -0
- data/spec/integration/discriminator_value_spec.rb +207 -0
- data/spec/integration/{matchable_spec.rb → matcher_examples_spec.rb} +120 -41
- data/spec/integration/matcher_operator_data/all.yml +140 -0
- data/spec/integration/matcher_operator_data/and.yml +93 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +363 -0
- data/spec/integration/matcher_operator_data/elem_match_expr.yml +213 -0
- data/spec/integration/matcher_operator_data/eq.yml +191 -0
- data/spec/integration/matcher_operator_data/exists.yml +213 -0
- data/spec/integration/matcher_operator_data/generic_op.yml +17 -0
- data/spec/integration/matcher_operator_data/gt.yml +132 -0
- data/spec/integration/matcher_operator_data/gte.yml +132 -0
- data/spec/integration/matcher_operator_data/implicit.yml +331 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +16 -0
- data/spec/integration/matcher_operator_data/in.yml +194 -0
- data/spec/integration/matcher_operator_data/invalid_op.yml +59 -0
- data/spec/integration/matcher_operator_data/invalid_syntax.yml +39 -0
- data/spec/integration/matcher_operator_data/lt.yml +132 -0
- data/spec/integration/matcher_operator_data/lte.yml +132 -0
- data/spec/integration/matcher_operator_data/multiple.yml +29 -0
- data/spec/integration/matcher_operator_data/ne.yml +150 -0
- data/spec/integration/matcher_operator_data/nin.yml +114 -0
- data/spec/integration/matcher_operator_data/nor.yml +126 -0
- data/spec/integration/matcher_operator_data/not.yml +196 -0
- data/spec/integration/matcher_operator_data/or.yml +137 -0
- data/spec/integration/matcher_operator_data/regex.yml +174 -0
- data/spec/integration/matcher_operator_data/regex_options.yml +72 -0
- data/spec/integration/matcher_operator_data/size.yml +174 -0
- data/spec/integration/matcher_operator_spec.rb +100 -0
- data/spec/integration/matcher_spec.rb +189 -0
- data/spec/integration/server_query_spec.rb +142 -0
- data/spec/integration/shardable_spec.rb +20 -4
- data/spec/integration/stringified_symbol_field_spec.rb +190 -0
- data/spec/lite_spec_helper.rb +4 -2
- data/spec/mongoid/association/accessors_spec.rb +238 -63
- data/spec/mongoid/association/depending_spec.rb +78 -26
- data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +33 -0
- data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
- data/spec/mongoid/association/embedded/embeds_one_models.rb +1 -0
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +138 -0
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +105 -0
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +460 -186
- data/spec/mongoid/association/referenced/has_many_models.rb +21 -0
- data/spec/mongoid/association/referenced/has_one_models.rb +21 -0
- data/spec/mongoid/association/referenced/has_one_spec.rb +1 -1
- data/spec/mongoid/atomic/modifiers_spec.rb +47 -0
- data/spec/mongoid/atomic_spec.rb +23 -0
- data/spec/mongoid/attributes/nested_spec.rb +1 -1
- data/spec/mongoid/clients/factory_spec.rb +45 -8
- data/spec/mongoid/clients/options_spec.rb +9 -9
- data/spec/mongoid/clients/sessions_spec.rb +1 -6
- data/spec/mongoid/config_spec.rb +28 -0
- data/spec/mongoid/contextual/geo_near_spec.rb +11 -2
- data/spec/mongoid/contextual/mongo_spec.rb +70 -16
- data/spec/mongoid/copyable_spec.rb +197 -18
- data/spec/mongoid/copyable_spec_models.rb +28 -0
- data/spec/mongoid/criteria/queryable/extensions/regexp_raw_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +19 -7
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +28 -1
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +84 -82
- data/spec/mongoid/criteria_spec.rb +204 -39
- data/spec/mongoid/document_spec.rb +89 -15
- data/spec/mongoid/equality_spec.rb +0 -1
- data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
- data/spec/mongoid/errors/no_client_config_spec.rb +2 -2
- data/spec/mongoid/errors/no_client_database_spec.rb +3 -3
- data/spec/mongoid/errors/no_client_hosts_spec.rb +3 -3
- data/spec/mongoid/extensions/stringified_symbol_spec.rb +85 -0
- data/spec/mongoid/factory_spec.rb +261 -28
- data/spec/mongoid/fields_spec.rb +72 -3
- data/spec/mongoid/findable_spec.rb +32 -0
- data/spec/mongoid/indexable_spec.rb +28 -2
- data/spec/mongoid/inspectable_spec.rb +29 -2
- data/spec/mongoid/interceptable_spec.rb +2 -2
- data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +259 -0
- data/spec/mongoid/matcher/extract_attribute_spec.rb +47 -0
- data/spec/mongoid/persistable/creatable_spec.rb +108 -25
- data/spec/mongoid/persistable/deletable_spec.rb +86 -0
- data/spec/mongoid/persistable/savable_spec.rb +174 -16
- data/spec/mongoid/query_cache_middleware_spec.rb +16 -3
- data/spec/mongoid/query_cache_spec.rb +496 -28
- data/spec/mongoid/reloadable_spec.rb +72 -0
- data/spec/mongoid/serializable_spec.rb +21 -3
- data/spec/mongoid/traversable_spec.rb +1100 -0
- data/spec/shared/LICENSE +20 -0
- data/spec/shared/lib/mrss/child_process_helper.rb +80 -0
- data/spec/shared/lib/mrss/constraints.rb +303 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +175 -0
- data/spec/shared/lib/mrss/spec_organizer.rb +149 -0
- data/spec/spec_helper.rb +4 -2
- data/spec/support/constraints.rb +20 -222
- data/spec/support/helpers.rb +1 -1
- data/spec/{app → support}/models/account.rb +0 -0
- data/spec/{app → support}/models/acolyte.rb +0 -0
- data/spec/{app → support}/models/actor.rb +1 -1
- data/spec/{app → support}/models/actress.rb +0 -0
- data/spec/{app → support}/models/address.rb +0 -0
- data/spec/{app → support}/models/address_component.rb +0 -0
- data/spec/{app → support}/models/address_number.rb +0 -0
- data/spec/{app → support}/models/agency.rb +0 -0
- data/spec/{app → support}/models/agent.rb +0 -0
- data/spec/{app → support}/models/album.rb +0 -0
- data/spec/{app → support}/models/alert.rb +0 -0
- data/spec/{app → support}/models/animal.rb +0 -0
- data/spec/{app → support}/models/answer.rb +0 -0
- data/spec/{app → support}/models/appointment.rb +0 -0
- data/spec/support/models/armrest.rb +10 -0
- data/spec/{app → support}/models/array_field.rb +0 -0
- data/spec/{app → support}/models/article.rb +0 -0
- data/spec/{app → support}/models/artist.rb +0 -0
- data/spec/{app → support}/models/artwork.rb +0 -0
- data/spec/{app → support}/models/audio.rb +0 -0
- data/spec/{app → support}/models/augmentation.rb +0 -0
- data/spec/{app → support}/models/author.rb +0 -0
- data/spec/{app → support}/models/baby.rb +0 -0
- data/spec/{app → support}/models/band.rb +0 -0
- data/spec/{app → support}/models/bar.rb +0 -0
- data/spec/{app → support}/models/basic.rb +0 -0
- data/spec/{app → support}/models/bed.rb +0 -0
- data/spec/{app → support}/models/big_palette.rb +0 -0
- data/spec/{app → support}/models/birthday.rb +0 -0
- data/spec/{app → support}/models/bomb.rb +0 -0
- data/spec/{app → support}/models/book.rb +0 -0
- data/spec/{app → support}/models/breed.rb +0 -0
- data/spec/{app → support}/models/browser.rb +1 -1
- data/spec/{app → support}/models/building.rb +0 -0
- data/spec/{app → support}/models/building_address.rb +0 -0
- data/spec/{app → support}/models/bus.rb +0 -0
- data/spec/{app → support}/models/business.rb +0 -0
- data/spec/{app → support}/models/callback_test.rb +0 -0
- data/spec/{app → support}/models/canvas.rb +1 -1
- data/spec/{app → support}/models/car.rb +0 -0
- data/spec/{app → support}/models/cat.rb +0 -0
- data/spec/{app → support}/models/category.rb +0 -0
- data/spec/{app → support}/models/child.rb +0 -0
- data/spec/{app → support}/models/child_doc.rb +0 -0
- data/spec/{app → support}/models/church.rb +0 -0
- data/spec/{app → support}/models/circle.rb +0 -0
- data/spec/{app → support}/models/circuit.rb +0 -0
- data/spec/{app → support}/models/circus.rb +0 -0
- data/spec/{app → support}/models/code.rb +0 -0
- data/spec/{app → support}/models/coding.rb +1 -1
- data/spec/{app → support}/models/coding/pull_request.rb +0 -0
- data/spec/{app → support}/models/comment.rb +0 -0
- data/spec/{app → support}/models/company.rb +0 -0
- data/spec/{app → support}/models/consumption_period.rb +0 -0
- data/spec/{app → support}/models/contextable_item.rb +0 -0
- data/spec/{app → support}/models/contractor.rb +0 -0
- data/spec/{app → support}/models/cookie.rb +0 -0
- data/spec/{app → support}/models/country_code.rb +0 -0
- data/spec/{app → support}/models/courier_job.rb +0 -0
- data/spec/support/models/crate.rb +13 -0
- data/spec/support/models/deed.rb +8 -0
- data/spec/{app → support}/models/definition.rb +0 -0
- data/spec/{app → support}/models/delegating_patient.rb +0 -0
- data/spec/{app → support}/models/description.rb +0 -0
- data/spec/{app → support}/models/dictionary.rb +0 -0
- data/spec/{app → support}/models/division.rb +0 -0
- data/spec/{app → support}/models/doctor.rb +0 -0
- data/spec/{app → support}/models/dog.rb +0 -0
- data/spec/{app → support}/models/dokument.rb +0 -0
- data/spec/{app → support}/models/draft.rb +0 -0
- data/spec/{app → support}/models/dragon.rb +0 -0
- data/spec/{app → support}/models/driver.rb +1 -1
- data/spec/{app → support}/models/drug.rb +0 -0
- data/spec/{app → support}/models/dungeon.rb +0 -0
- data/spec/{app → support}/models/edit.rb +0 -0
- data/spec/{app → support}/models/email.rb +0 -0
- data/spec/{app → support}/models/employer.rb +0 -0
- data/spec/{app → support}/models/entry.rb +0 -0
- data/spec/{app → support}/models/eraser.rb +0 -0
- data/spec/{app → support}/models/even.rb +0 -0
- data/spec/{app → support}/models/event.rb +0 -0
- data/spec/{app → support}/models/exhibition.rb +0 -0
- data/spec/{app → support}/models/exhibitor.rb +0 -0
- data/spec/{app → support}/models/explosion.rb +0 -0
- data/spec/{app → support}/models/eye.rb +0 -0
- data/spec/{app → support}/models/eye_bowl.rb +0 -0
- data/spec/{app → support}/models/face.rb +0 -0
- data/spec/{app → support}/models/favorite.rb +0 -0
- data/spec/{app → support}/models/filesystem.rb +0 -0
- data/spec/{app → support}/models/fire_hydrant.rb +0 -0
- data/spec/{app → support}/models/firefox.rb +0 -0
- data/spec/{app → support}/models/fish.rb +0 -0
- data/spec/{app → support}/models/folder.rb +0 -0
- data/spec/{app → support}/models/folder_item.rb +0 -0
- data/spec/{app → support}/models/fruits.rb +0 -0
- data/spec/{app → support}/models/game.rb +0 -0
- data/spec/{app → support}/models/ghost.rb +0 -0
- data/spec/support/models/guitar.rb +5 -0
- data/spec/{app → support}/models/home.rb +0 -0
- data/spec/{app → support}/models/house.rb +0 -0
- data/spec/{app → support}/models/html_writer.rb +0 -0
- data/spec/{app → support}/models/id_key.rb +0 -0
- data/spec/support/models/idnodef.rb +8 -0
- data/spec/{app → support}/models/image.rb +0 -0
- data/spec/{app → support}/models/implant.rb +0 -0
- data/spec/support/models/instrument.rb +9 -0
- data/spec/{app → support}/models/item.rb +1 -1
- data/spec/{app → support}/models/jar.rb +0 -0
- data/spec/{app → support}/models/kaleidoscope.rb +0 -0
- data/spec/{app → support}/models/kangaroo.rb +0 -0
- data/spec/{app → support}/models/label.rb +0 -0
- data/spec/{app → support}/models/language.rb +0 -0
- data/spec/{app → support}/models/lat_lng.rb +0 -0
- data/spec/{app → support}/models/league.rb +0 -0
- data/spec/{app → support}/models/learner.rb +0 -0
- data/spec/{app → support}/models/line_item.rb +0 -0
- data/spec/{app → support}/models/location.rb +0 -0
- data/spec/{app → support}/models/login.rb +0 -0
- data/spec/{app → support}/models/manufacturer.rb +0 -0
- data/spec/{app → support}/models/meat.rb +0 -0
- data/spec/{app → support}/models/membership.rb +0 -0
- data/spec/{app → support}/models/message.rb +0 -0
- data/spec/{app → support}/models/minim.rb +0 -0
- data/spec/{app → support}/models/mixed_drink.rb +0 -0
- data/spec/support/models/mop.rb +16 -0
- data/spec/{app → support}/models/movie.rb +0 -0
- data/spec/{app → support}/models/my_hash.rb +0 -0
- data/spec/{app → support}/models/name.rb +0 -0
- data/spec/{app → support}/models/name_only.rb +0 -0
- data/spec/{app → support}/models/node.rb +0 -0
- data/spec/{app → support}/models/note.rb +0 -0
- data/spec/{app → support}/models/odd.rb +0 -0
- data/spec/support/models/order.rb +11 -0
- data/spec/{app → support}/models/ordered_post.rb +0 -0
- data/spec/{app → support}/models/ordered_preference.rb +0 -0
- data/spec/{app → support}/models/oscar.rb +0 -0
- data/spec/{app → support}/models/other_owner_object.rb +0 -0
- data/spec/{app → support}/models/override.rb +0 -0
- data/spec/{app → support}/models/ownable.rb +0 -0
- data/spec/{app → support}/models/owner.rb +2 -0
- data/spec/{app → support}/models/pack.rb +0 -0
- data/spec/{app → support}/models/page.rb +0 -0
- data/spec/{app → support}/models/page_question.rb +0 -0
- data/spec/{app → support}/models/palette.rb +1 -1
- data/spec/{app → support}/models/parent.rb +0 -0
- data/spec/{app → support}/models/parent_doc.rb +0 -0
- data/spec/{app → support}/models/passport.rb +1 -0
- data/spec/{app → support}/models/patient.rb +0 -0
- data/spec/{app → support}/models/pdf_writer.rb +0 -0
- data/spec/{app → support}/models/pencil.rb +0 -0
- data/spec/{app → support}/models/person.rb +3 -1
- data/spec/{app → support}/models/pet.rb +0 -0
- data/spec/{app → support}/models/pet_owner.rb +0 -0
- data/spec/{app → support}/models/phone.rb +1 -0
- data/spec/support/models/piano.rb +5 -0
- data/spec/{app → support}/models/pizza.rb +0 -0
- data/spec/{app → support}/models/player.rb +0 -0
- data/spec/{app → support}/models/post.rb +0 -0
- data/spec/{app → support}/models/post_genre.rb +0 -0
- data/spec/{app → support}/models/powerup.rb +0 -0
- data/spec/{app → support}/models/preference.rb +0 -0
- data/spec/{app → support}/models/princess.rb +0 -0
- data/spec/{app → support}/models/product.rb +0 -0
- data/spec/support/models/profile.rb +18 -0
- data/spec/{app → support}/models/pronunciation.rb +0 -0
- data/spec/{app → support}/models/pub.rb +0 -0
- data/spec/support/models/publication.rb +5 -0
- data/spec/{app → support}/models/publication/encyclopedia.rb +0 -0
- data/spec/{app → support}/models/publication/review.rb +0 -0
- data/spec/{app → support}/models/purchase.rb +0 -0
- data/spec/{app → support}/models/question.rb +0 -0
- data/spec/{app → support}/models/quiz.rb +0 -0
- data/spec/{app → support}/models/rating.rb +0 -0
- data/spec/{app → support}/models/record.rb +0 -0
- data/spec/{app → support}/models/registry.rb +0 -0
- data/spec/{app → support}/models/role.rb +0 -0
- data/spec/{app → support}/models/root_category.rb +0 -0
- data/spec/{app → support}/models/sandwich.rb +0 -0
- data/spec/{app → support}/models/scheduler.rb +0 -0
- data/spec/{app/models/profile.rb → support/models/scribe.rb} +2 -2
- data/spec/support/models/seat.rb +25 -0
- data/spec/{app → support}/models/seo.rb +0 -0
- data/spec/{app → support}/models/series.rb +1 -0
- data/spec/{app → support}/models/server.rb +0 -0
- data/spec/{app → support}/models/service.rb +0 -0
- data/spec/{app → support}/models/shape.rb +2 -2
- data/spec/{app → support}/models/shelf.rb +0 -0
- data/spec/{app → support}/models/shipment_address.rb +0 -0
- data/spec/{app → support}/models/shipping_container.rb +0 -0
- data/spec/{app → support}/models/shipping_pack.rb +0 -0
- data/spec/{app → support}/models/shop.rb +0 -0
- data/spec/{app → support}/models/short_agent.rb +0 -0
- data/spec/{app → support}/models/short_quiz.rb +0 -0
- data/spec/{app → support}/models/simple.rb +0 -0
- data/spec/{app → support}/models/slave.rb +0 -0
- data/spec/{app → support}/models/song.rb +0 -0
- data/spec/{app → support}/models/sound.rb +0 -0
- data/spec/{app → support}/models/square.rb +0 -0
- data/spec/{app → support}/models/staff.rb +0 -0
- data/spec/{app → support}/models/store_as_dup_test1.rb +0 -0
- data/spec/{app → support}/models/store_as_dup_test2.rb +0 -0
- data/spec/{app → support}/models/store_as_dup_test3.rb +0 -0
- data/spec/{app → support}/models/store_as_dup_test4.rb +0 -0
- data/spec/{app → support}/models/strategy.rb +0 -0
- data/spec/{app → support}/models/sub_item.rb +0 -0
- data/spec/{app → support}/models/subscription.rb +0 -0
- data/spec/{app → support}/models/survey.rb +0 -0
- data/spec/{app → support}/models/symptom.rb +0 -0
- data/spec/support/models/system_role.rb +7 -0
- data/spec/{app → support}/models/tag.rb +0 -0
- data/spec/{app → support}/models/target.rb +0 -0
- data/spec/{app → support}/models/template.rb +0 -0
- data/spec/{app → support}/models/thing.rb +0 -0
- data/spec/{app → support}/models/title.rb +0 -0
- data/spec/{app → support}/models/tool.rb +2 -2
- data/spec/{app → support}/models/topping.rb +0 -0
- data/spec/support/models/toy.rb +10 -0
- data/spec/{app → support}/models/track.rb +0 -0
- data/spec/{app → support}/models/translation.rb +0 -0
- data/spec/{app → support}/models/tree.rb +0 -0
- data/spec/{app → support}/models/truck.rb +2 -0
- data/spec/{app → support}/models/updatable.rb +0 -0
- data/spec/{app → support}/models/user.rb +0 -0
- data/spec/{app → support}/models/user_account.rb +0 -0
- data/spec/{app → support}/models/validation_callback.rb +0 -0
- data/spec/{app → support}/models/vehicle.rb +7 -2
- data/spec/{app → support}/models/version.rb +0 -0
- data/spec/{app → support}/models/vertex.rb +0 -0
- data/spec/{app → support}/models/vet_visit.rb +0 -0
- data/spec/{app → support}/models/video.rb +0 -0
- data/spec/{app → support}/models/video_game.rb +0 -0
- data/spec/{app → support}/models/weapon.rb +0 -0
- data/spec/{app → support}/models/wiki_page.rb +1 -0
- data/spec/{app → support}/models/word.rb +0 -0
- data/spec/{app → support}/models/word_origin.rb +0 -0
- data/spec/{app → support}/models/writer.rb +2 -2
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +1 -1
- metadata +857 -739
- metadata.gz.sig +0 -0
- data/lib/mongoid/matchable/all.rb +0 -30
- data/lib/mongoid/matchable/and.rb +0 -32
- data/lib/mongoid/matchable/default.rb +0 -121
- data/lib/mongoid/matchable/elem_match.rb +0 -36
- data/lib/mongoid/matchable/eq.rb +0 -23
- data/lib/mongoid/matchable/exists.rb +0 -25
- data/lib/mongoid/matchable/gt.rb +0 -25
- data/lib/mongoid/matchable/gte.rb +0 -25
- data/lib/mongoid/matchable/in.rb +0 -26
- data/lib/mongoid/matchable/lt.rb +0 -25
- data/lib/mongoid/matchable/lte.rb +0 -25
- data/lib/mongoid/matchable/ne.rb +0 -23
- data/lib/mongoid/matchable/nin.rb +0 -24
- data/lib/mongoid/matchable/nor.rb +0 -38
- data/lib/mongoid/matchable/or.rb +0 -35
- data/lib/mongoid/matchable/regexp.rb +0 -30
- data/lib/mongoid/matchable/size.rb +0 -23
- data/spec/app/models/publication.rb +0 -5
- data/spec/mongoid/matchable/all_spec.rb +0 -34
- data/spec/mongoid/matchable/and_spec.rb +0 -190
- data/spec/mongoid/matchable/default_spec.rb +0 -140
- data/spec/mongoid/matchable/elem_match_spec.rb +0 -109
- data/spec/mongoid/matchable/eq_spec.rb +0 -49
- data/spec/mongoid/matchable/exists_spec.rb +0 -60
- data/spec/mongoid/matchable/gt_spec.rb +0 -89
- data/spec/mongoid/matchable/gte_spec.rb +0 -87
- data/spec/mongoid/matchable/in_spec.rb +0 -52
- data/spec/mongoid/matchable/lt_spec.rb +0 -88
- data/spec/mongoid/matchable/lte_spec.rb +0 -88
- data/spec/mongoid/matchable/ne_spec.rb +0 -49
- data/spec/mongoid/matchable/nin_spec.rb +0 -51
- data/spec/mongoid/matchable/nor_spec.rb +0 -210
- data/spec/mongoid/matchable/or_spec.rb +0 -134
- data/spec/mongoid/matchable/regexp_spec.rb +0 -62
- data/spec/mongoid/matchable/size_spec.rb +0 -28
- data/spec/mongoid/matchable_spec.rb +0 -856
- data/spec/support/child_process_helper.rb +0 -76
- data/spec/support/lite_constraints.rb +0 -22
data/lib/mongoid/fields.rb
CHANGED
|
@@ -12,6 +12,8 @@ module Mongoid
|
|
|
12
12
|
module Fields
|
|
13
13
|
extend ActiveSupport::Concern
|
|
14
14
|
|
|
15
|
+
StringifiedSymbol = Mongoid::StringifiedSymbol
|
|
16
|
+
|
|
15
17
|
# For fields defined with symbols use the correct class.
|
|
16
18
|
#
|
|
17
19
|
# @since 4.0.0
|
|
@@ -30,6 +32,7 @@ module Mongoid
|
|
|
30
32
|
regexp: Regexp,
|
|
31
33
|
set: Set,
|
|
32
34
|
string: String,
|
|
35
|
+
stringified_symbol: StringifiedSymbol,
|
|
33
36
|
symbol: Symbol,
|
|
34
37
|
time: Time
|
|
35
38
|
}.with_indifferent_access
|
|
@@ -39,7 +39,8 @@ module Mongoid
|
|
|
39
39
|
#
|
|
40
40
|
# @since 3.0.0
|
|
41
41
|
def validate(klass, name, options)
|
|
42
|
-
|
|
42
|
+
validate_field_name(klass, name)
|
|
43
|
+
validate_name_uniqueness(klass, name, options)
|
|
43
44
|
validate_options(klass, name, options)
|
|
44
45
|
end
|
|
45
46
|
|
|
@@ -61,28 +62,40 @@ module Mongoid
|
|
|
61
62
|
end
|
|
62
63
|
end
|
|
63
64
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
# Determine if the field name is allowed, if not raise an error.
|
|
67
|
-
#
|
|
68
|
-
# @api private
|
|
65
|
+
# Determine if the field name is valid, if not raise an error.
|
|
69
66
|
#
|
|
70
67
|
# @example Check the field name.
|
|
71
|
-
# Macro.
|
|
68
|
+
# Macro.validate_field_name(Model, :name)
|
|
72
69
|
#
|
|
73
70
|
# @param [ Class ] klass The model class.
|
|
74
71
|
# @param [ Symbol ] name The field name.
|
|
75
72
|
#
|
|
76
73
|
# @raise [ Errors::InvalidField ] If the name is not allowed.
|
|
77
74
|
#
|
|
78
|
-
# @
|
|
79
|
-
def
|
|
75
|
+
# @api private
|
|
76
|
+
def validate_field_name(klass, name)
|
|
80
77
|
[name, "#{name}?".to_sym, "#{name}=".to_sym].each do |n|
|
|
81
78
|
if Mongoid.destructive_fields.include?(n)
|
|
82
79
|
raise Errors::InvalidField.new(klass, n)
|
|
83
80
|
end
|
|
84
81
|
end
|
|
82
|
+
end
|
|
85
83
|
|
|
84
|
+
private
|
|
85
|
+
|
|
86
|
+
# Determine if the field name is unique, if not raise an error.
|
|
87
|
+
#
|
|
88
|
+
# @example Check the field name.
|
|
89
|
+
# Macro.validate_name_uniqueness(Model, :name, {})
|
|
90
|
+
#
|
|
91
|
+
# @param [ Class ] klass The model class.
|
|
92
|
+
# @param [ Symbol ] name The field name.
|
|
93
|
+
# @param [ Hash ] options The provided options.
|
|
94
|
+
#
|
|
95
|
+
# @raise [ Errors::InvalidField ] If the name is not allowed.
|
|
96
|
+
#
|
|
97
|
+
# @api private
|
|
98
|
+
def validate_name_uniqueness(klass, name, options)
|
|
86
99
|
if !options[:overwrite] && klass.fields.keys.include?(name.to_s)
|
|
87
100
|
if Mongoid.duplicate_fields_exception
|
|
88
101
|
raise Errors::InvalidField.new(klass, name)
|
|
@@ -113,7 +126,10 @@ module Mongoid
|
|
|
113
126
|
end
|
|
114
127
|
|
|
115
128
|
if option == :type && options[option] == Symbol
|
|
116
|
-
|
|
129
|
+
@field_type_is_symbol_warned ||= begin
|
|
130
|
+
Mongoid.logger.warn(FIELD_TYPE_IS_SYMBOL)
|
|
131
|
+
true
|
|
132
|
+
end
|
|
117
133
|
end
|
|
118
134
|
end
|
|
119
135
|
end
|
data/lib/mongoid/findable.rb
CHANGED
|
@@ -60,6 +60,16 @@ module Mongoid
|
|
|
60
60
|
with_default_scope.count
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
+
# Returns an estimated count of records in the database.
|
|
64
|
+
#
|
|
65
|
+
# @example Get the count of matching documents.
|
|
66
|
+
# Person.estimated_count
|
|
67
|
+
#
|
|
68
|
+
# @return [ Integer ] The number of matching documents.
|
|
69
|
+
def estimated_count
|
|
70
|
+
with_default_scope.estimated_count
|
|
71
|
+
end
|
|
72
|
+
|
|
63
73
|
# Returns true if count is zero
|
|
64
74
|
#
|
|
65
75
|
# @example Are there no saved documents for this model?
|
|
@@ -81,20 +91,46 @@ module Mongoid
|
|
|
81
91
|
with_default_scope.exists?
|
|
82
92
|
end
|
|
83
93
|
|
|
84
|
-
#
|
|
85
|
-
#
|
|
86
|
-
# If a
|
|
87
|
-
#
|
|
88
|
-
#
|
|
89
|
-
#
|
|
90
|
-
#
|
|
91
|
-
#
|
|
92
|
-
#
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
96
|
-
#
|
|
97
|
-
#
|
|
94
|
+
# Finds a +Document+ or multiple documents by their _id values.
|
|
95
|
+
#
|
|
96
|
+
# If a single non-Array argument is given, this argument is interpreted
|
|
97
|
+
# as the _id value of a document to find. If there is a matching document
|
|
98
|
+
# in the database, this document is returned; otherwise, if the
|
|
99
|
+
# +raise_not_found_error+ Mongoid configuration option is truthy
|
|
100
|
+
# (which is the default), +Errors::DocumentNotFound+ is raised, and if
|
|
101
|
+
# +raise_not_found_error+ is falsy, +find+ returns +nil+.
|
|
102
|
+
#
|
|
103
|
+
# If multiple arguments are given, or an Array argument is given, the
|
|
104
|
+
# array is flattened and each array element is interpreted as the _id
|
|
105
|
+
# value of the document to find. Mongoid then attempts to retrieve all
|
|
106
|
+
# documents with the provided _id values. The return value is an array
|
|
107
|
+
# of found documents. Each document appears one time in the returned array,
|
|
108
|
+
# even if its _id is given multiple times in the argument to +find+.
|
|
109
|
+
# If the +raise_not_found_error+ Mongoid configuration option is truthy,
|
|
110
|
+
# +Errors::DocumentNotFound+ exception is raised if any of the specified
|
|
111
|
+
# _ids were not found in the database. If the ++raise_not_found_error+
|
|
112
|
+
# Mongoid configuration option is falsy, only those documents which are
|
|
113
|
+
# found are returned; if no documents are found, the return value is an
|
|
114
|
+
# empty array.
|
|
115
|
+
#
|
|
116
|
+
# Note that MongoDB does not allow the _id field to be an array.
|
|
117
|
+
#
|
|
118
|
+
# The argument undergoes customary Mongoid type conversions based on
|
|
119
|
+
# the type declared for the _id field. By default the _id field is a
|
|
120
|
+
# +BSON::ObjectId+; this allows strings to be passed to +find+ and the
|
|
121
|
+
# strings will be transparently converted to +BSON::ObjectId+ instances
|
|
122
|
+
# during query construction.
|
|
123
|
+
#
|
|
124
|
+
# The +find+ method takes into account the default scope defined on the
|
|
125
|
+
# model class, if any.
|
|
126
|
+
#
|
|
127
|
+
# @param [ Object | Array<Object> ] args The _id values to find or an
|
|
128
|
+
# array thereof.
|
|
129
|
+
#
|
|
130
|
+
# @return [ Document | Array<Document> | nil ] A document or matching documents.
|
|
131
|
+
#
|
|
132
|
+
# @raise Errors::DocumentNotFound If not all documents are found and
|
|
133
|
+
# the +raise_not_found_error+ Mongoid configuration option is truthy.
|
|
98
134
|
def find(*args)
|
|
99
135
|
with_default_scope.find(*args)
|
|
100
136
|
end
|
data/lib/mongoid/indexable.rb
CHANGED
|
@@ -82,8 +82,8 @@ module Mongoid
|
|
|
82
82
|
#
|
|
83
83
|
# @since 1.0.0
|
|
84
84
|
def add_indexes
|
|
85
|
-
if hereditary? && !index_keys.include?(
|
|
86
|
-
index({
|
|
85
|
+
if hereditary? && !index_keys.include?(self.discriminator_key.to_sym => 1)
|
|
86
|
+
index({ self.discriminator_key.to_sym => 1 }, unique: false, background: true)
|
|
87
87
|
end
|
|
88
88
|
true
|
|
89
89
|
end
|
data/lib/mongoid/matchable.rb
CHANGED
|
@@ -1,24 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
# encoding: utf-8
|
|
3
3
|
|
|
4
|
-
require "mongoid/matchable/default"
|
|
5
|
-
require "mongoid/matchable/all"
|
|
6
|
-
require "mongoid/matchable/and"
|
|
7
|
-
require "mongoid/matchable/elem_match"
|
|
8
|
-
require "mongoid/matchable/eq"
|
|
9
|
-
require "mongoid/matchable/exists"
|
|
10
|
-
require "mongoid/matchable/gt"
|
|
11
|
-
require "mongoid/matchable/gte"
|
|
12
|
-
require "mongoid/matchable/in"
|
|
13
|
-
require "mongoid/matchable/lt"
|
|
14
|
-
require "mongoid/matchable/lte"
|
|
15
|
-
require "mongoid/matchable/ne"
|
|
16
|
-
require "mongoid/matchable/nin"
|
|
17
|
-
require "mongoid/matchable/nor"
|
|
18
|
-
require "mongoid/matchable/or"
|
|
19
|
-
require "mongoid/matchable/regexp"
|
|
20
|
-
require "mongoid/matchable/size"
|
|
21
|
-
|
|
22
4
|
module Mongoid
|
|
23
5
|
|
|
24
6
|
# This module contains all the behavior for Ruby implementations of MongoDB
|
|
@@ -28,27 +10,6 @@ module Mongoid
|
|
|
28
10
|
module Matchable
|
|
29
11
|
extend ActiveSupport::Concern
|
|
30
12
|
|
|
31
|
-
# Hash lookup for the matcher for a specific operation.
|
|
32
|
-
#
|
|
33
|
-
# @since 1.0.0
|
|
34
|
-
MATCHERS = {
|
|
35
|
-
"$all" => All,
|
|
36
|
-
"$and" => And,
|
|
37
|
-
"$elemMatch" => ElemMatch,
|
|
38
|
-
"$eq" => Eq,
|
|
39
|
-
"$exists" => Exists,
|
|
40
|
-
"$gt" => Gt,
|
|
41
|
-
"$gte" => Gte,
|
|
42
|
-
"$in" => In,
|
|
43
|
-
"$lt" => Lt,
|
|
44
|
-
"$lte" => Lte,
|
|
45
|
-
"$ne" => Ne,
|
|
46
|
-
"$nin" => Nin,
|
|
47
|
-
"$nor" => Nor,
|
|
48
|
-
"$or" => Or,
|
|
49
|
-
"$size" => Size,
|
|
50
|
-
}.with_indifferent_access.freeze
|
|
51
|
-
|
|
52
13
|
# Determines if this document has the attributes to match the supplied
|
|
53
14
|
# MongoDB selector. Used for matching on embedded associations.
|
|
54
15
|
#
|
|
@@ -61,116 +22,7 @@ module Mongoid
|
|
|
61
22
|
#
|
|
62
23
|
# @since 1.0.0
|
|
63
24
|
def _matches?(selector)
|
|
64
|
-
|
|
65
|
-
if value.is_a?(Hash)
|
|
66
|
-
value.each do |item|
|
|
67
|
-
if item[0].to_s == "$not".freeze
|
|
68
|
-
item = item[1]
|
|
69
|
-
return false if matcher(key, item)._matches?(item)
|
|
70
|
-
else
|
|
71
|
-
return false unless matcher(key, Hash[*item])._matches?(Hash[*item])
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
else
|
|
75
|
-
return false unless matcher(key, value)._matches?(value)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
true
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
private
|
|
82
|
-
|
|
83
|
-
# Get the matcher for the supplied key and value. Will determine the class
|
|
84
|
-
# name from the key.
|
|
85
|
-
#
|
|
86
|
-
# @example Get the matcher.
|
|
87
|
-
# document.matcher(:title, { "$in" => [ "test" ] })
|
|
88
|
-
#
|
|
89
|
-
# @param [ Symbol, String ] key The field name.
|
|
90
|
-
# @param [ Object, Hash ] value The value or selector.
|
|
91
|
-
#
|
|
92
|
-
# @return [ Matcher ] The matcher.
|
|
93
|
-
#
|
|
94
|
-
# @since 2.0.0.rc.7
|
|
95
|
-
# @api private
|
|
96
|
-
def matcher(key, value)
|
|
97
|
-
Matchable.matcher(self, key, value)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
class << self
|
|
101
|
-
|
|
102
|
-
# Get the matcher for the supplied key and value. Will determine the class
|
|
103
|
-
# name from the key.
|
|
104
|
-
#
|
|
105
|
-
# @api private
|
|
106
|
-
#
|
|
107
|
-
# @example Get the matcher.
|
|
108
|
-
# Matchable.matcher(document, :title, { "$in" => [ "test" ] })
|
|
109
|
-
#
|
|
110
|
-
# @param [ Document ] document The document to check.
|
|
111
|
-
# @param [ Symbol, String ] key The field name.
|
|
112
|
-
# @param [ Object, Hash ] value The value or selector.
|
|
113
|
-
#
|
|
114
|
-
# @return [ Matcher ] The matcher.
|
|
115
|
-
#
|
|
116
|
-
# @since 2.0.0.rc.7
|
|
117
|
-
def matcher(document, key, value)
|
|
118
|
-
if value.is_a?(Hash)
|
|
119
|
-
matcher = MATCHERS[value.keys.first]
|
|
120
|
-
if matcher
|
|
121
|
-
matcher.new(extract_attribute(document, key))
|
|
122
|
-
else
|
|
123
|
-
Default.new(extract_attribute(document, key))
|
|
124
|
-
end
|
|
125
|
-
elsif value.regexp?
|
|
126
|
-
Regexp.new(extract_attribute(document, key))
|
|
127
|
-
else
|
|
128
|
-
case key.to_s
|
|
129
|
-
when "$or" then Or.new(value, document)
|
|
130
|
-
when "$and" then And.new(value, document)
|
|
131
|
-
when "$nor" then Nor.new(value, document)
|
|
132
|
-
else Default.new(extract_attribute(document, key))
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
private
|
|
138
|
-
|
|
139
|
-
# Extract the attribute from the key, being smarter about dot notation.
|
|
140
|
-
#
|
|
141
|
-
# @api private
|
|
142
|
-
#
|
|
143
|
-
# @example Extract the attribute.
|
|
144
|
-
# strategy.extract_attribute(doc, "info.field")
|
|
145
|
-
#
|
|
146
|
-
# @param [ Document ] document The document.
|
|
147
|
-
# @param [ String ] key The key.
|
|
148
|
-
#
|
|
149
|
-
# @return [ Object ] The value of the attribute.
|
|
150
|
-
#
|
|
151
|
-
# @since 2.2.1
|
|
152
|
-
# @api private
|
|
153
|
-
def extract_attribute(document, key)
|
|
154
|
-
if (key_string = key.to_s) =~ /.+\..+/
|
|
155
|
-
key_string.split('.').inject(document.send(:as_attributes)) do |_attribs, _key|
|
|
156
|
-
if _attribs.is_a?(::Array)
|
|
157
|
-
if _key =~ /\A\d+\z/ && _attribs.none? {|doc| doc.is_a?(Hash)}
|
|
158
|
-
_attribs.try(:[], _key.to_i)
|
|
159
|
-
else
|
|
160
|
-
_attribs.map { |doc| doc.try(:[], _key) }
|
|
161
|
-
end
|
|
162
|
-
else
|
|
163
|
-
_attribs.try(:[], _key)
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
else
|
|
167
|
-
if document.is_a?(Hash)
|
|
168
|
-
document[key_string]
|
|
169
|
-
else
|
|
170
|
-
document.attributes[key_string]
|
|
171
|
-
end
|
|
172
|
-
end
|
|
173
|
-
end
|
|
25
|
+
Matcher::Expression.matches?(self, selector)
|
|
174
26
|
end
|
|
175
27
|
end
|
|
176
28
|
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
module Mongoid
|
|
2
|
+
|
|
3
|
+
# @api private
|
|
4
|
+
module Matcher
|
|
5
|
+
|
|
6
|
+
# Extracts field values in the document at the specified key.
|
|
7
|
+
#
|
|
8
|
+
# The document can be a Hash or a model instance.
|
|
9
|
+
#
|
|
10
|
+
# The key is a valid MongoDB dot notation key. The following use cases are
|
|
11
|
+
# supported:
|
|
12
|
+
#
|
|
13
|
+
# - Simple field traversal (`foo`) - retrieves the field `foo` in the
|
|
14
|
+
# current document.
|
|
15
|
+
# - Hash/embedded document field traversal (`foo.bar`) - retrieves the
|
|
16
|
+
# field `foo` in the current document, then retrieves the field `bar`
|
|
17
|
+
# from the value of `foo`. Each path segment could descend into an
|
|
18
|
+
# embedded document or a hash field.
|
|
19
|
+
# - Array element retrieval (`foo.N`) - retrieves the Nth array element
|
|
20
|
+
# from the field `foo` which must be an array. N must be a non-negative
|
|
21
|
+
# integer.
|
|
22
|
+
# - Array traversal (`foo.bar`) - if `foo` is an array field, and
|
|
23
|
+
# the elements of `foo` are hashes or embedded documents, this returns
|
|
24
|
+
# an array of values of the `bar` field in each of the hashes in the
|
|
25
|
+
# `foo` array.
|
|
26
|
+
#
|
|
27
|
+
# The return value is a two-element array. The first element is the value
|
|
28
|
+
# retrieved, or an array of values. The second element is a boolean flag
|
|
29
|
+
# indicating whether an array was expanded at any point during the key
|
|
30
|
+
# traversal (because the respective document field was an array).
|
|
31
|
+
#
|
|
32
|
+
# @param [ Document | Hash ] document The document to extract from.
|
|
33
|
+
# @param [ String ] key The key path to extract.
|
|
34
|
+
#
|
|
35
|
+
# @return [ Array<true | false, Object | Array, true | false> ]
|
|
36
|
+
# Whether the value existed in the document, the extracted value
|
|
37
|
+
# and the array expansion flag.
|
|
38
|
+
module_function def extract_attribute(document, key)
|
|
39
|
+
if document.respond_to?(:as_attributes, true)
|
|
40
|
+
# If a document has hash fields, as_attributes would keep those fields
|
|
41
|
+
# as Hash instances which do not offer indifferent access.
|
|
42
|
+
# Convert to BSON::Document to get indifferent access on hash fields.
|
|
43
|
+
document = BSON::Document.new(document.send(:as_attributes))
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
src = document
|
|
47
|
+
expanded = false
|
|
48
|
+
exists = true
|
|
49
|
+
|
|
50
|
+
key.to_s.split('.').each do |field|
|
|
51
|
+
if (index = field.to_i).to_s == field
|
|
52
|
+
# Array indexing
|
|
53
|
+
if Array === src
|
|
54
|
+
exists = index < src.length
|
|
55
|
+
src = src[index]
|
|
56
|
+
else
|
|
57
|
+
# Trying to index something that is not an array
|
|
58
|
+
exists = false
|
|
59
|
+
src = nil
|
|
60
|
+
end
|
|
61
|
+
else
|
|
62
|
+
case src
|
|
63
|
+
when nil
|
|
64
|
+
exists = false
|
|
65
|
+
when Hash
|
|
66
|
+
exists = src.key?(field)
|
|
67
|
+
src = src[field]
|
|
68
|
+
when Array
|
|
69
|
+
expanded = true
|
|
70
|
+
exists = false
|
|
71
|
+
new = []
|
|
72
|
+
src.each do |doc|
|
|
73
|
+
case doc
|
|
74
|
+
when Hash
|
|
75
|
+
if doc.key?(field)
|
|
76
|
+
v = doc[field]
|
|
77
|
+
case v
|
|
78
|
+
when Array
|
|
79
|
+
new += v
|
|
80
|
+
else
|
|
81
|
+
new += [v]
|
|
82
|
+
end
|
|
83
|
+
exists = true
|
|
84
|
+
end
|
|
85
|
+
else
|
|
86
|
+
# Trying to hash index into a value that is not a hash
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
src = new
|
|
90
|
+
else
|
|
91
|
+
# Trying to descend into a field that is not a hash using
|
|
92
|
+
# dot notation.
|
|
93
|
+
exists = false
|
|
94
|
+
src = nil
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
[exists, src, expanded]
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
require 'mongoid/matcher/all'
|
|
105
|
+
require 'mongoid/matcher/and'
|
|
106
|
+
require 'mongoid/matcher/elem_match'
|
|
107
|
+
require 'mongoid/matcher/elem_match_expression'
|
|
108
|
+
require 'mongoid/matcher/eq'
|
|
109
|
+
require 'mongoid/matcher/eq_impl'
|
|
110
|
+
require 'mongoid/matcher/eq_impl_with_regexp'
|
|
111
|
+
require 'mongoid/matcher/exists'
|
|
112
|
+
require 'mongoid/matcher/expression'
|
|
113
|
+
require 'mongoid/matcher/field_expression'
|
|
114
|
+
require 'mongoid/matcher/gt'
|
|
115
|
+
require 'mongoid/matcher/gte'
|
|
116
|
+
require 'mongoid/matcher/in'
|
|
117
|
+
require 'mongoid/matcher/lt'
|
|
118
|
+
require 'mongoid/matcher/lte'
|
|
119
|
+
require 'mongoid/matcher/ne'
|
|
120
|
+
require 'mongoid/matcher/nin'
|
|
121
|
+
require 'mongoid/matcher/nor'
|
|
122
|
+
require 'mongoid/matcher/not'
|
|
123
|
+
require 'mongoid/matcher/or'
|
|
124
|
+
require 'mongoid/matcher/regex'
|
|
125
|
+
require 'mongoid/matcher/size'
|
|
126
|
+
require 'mongoid/matcher/expression_operator'
|
|
127
|
+
require 'mongoid/matcher/field_operator'
|