Descubra qué hay de nuevo en:
Para ver una lista de lanzamientos y notas de versión detalladas, consulta Mongoid Lanzamientos en GitHub.
Novedades en 9.1
La versión 9.1 incluye las siguientes nuevas funcionalidades, mejoras y correcciones:
Agrega el
Criteria#rawmétodo que permite recuperar resultados como hashes sin procesar. Para obtener más información, consulte el Consulte la sección "Devolver datos sin procesar" de la guía "Modificar resultados de consulta".Mejora la funcionalidad de almacenamiento en caché al modificar el comportamiento de
cache_keypara no insertar una marca de tiempo cuandocache_versiondevuelve un valor diferente de nul. En su lugar, la marca de tiempo se utiliza como la versión de la entrada para reducir la rotación de claves.Este cambio también agrega el método
cache_versional móduloMongoid::Document. Si el formato de clave de caché introducido en esta versión presenta un problema en tu aplicación, puedes revertir al formato original definiendo el métodocache_versioncomonil:module Mongoid module Document def cache_version = nil end end Actualiza el método
serializable_hashpara incluir una nueva opciónMongoid::Config.serializable_hash_with_legacy_only, cuyo valor predeterminado estrue. Cuando esta opción está habilitada, el controlador Ruby utiliza el comportamiento heredadoserializable_hash. Este comportamiento devuelve todas las claves cuando se pasa un array vacío para la opción:only. Mongoid dejará de utilizar este comportamiento heredado en la versión10.0.Agrega la propiedad
Mongoid.isolation_level, que permite configurar el nivel de aislamiento por defecto para operaciones concurrentes. El nivel de aislamiento por defecto es:rails, que hereda el nivel de aislamiento desdeActiveSupport::IsolatedExecutionState. También puedes especificar la opción:threadpara la funcionalidad preexistente del nivel de aislamiento local del hilo o la opción:fiberpara heredar el estado interno de cualquier fibra principal.Agrega los métodos enumerables
any?,one?ymany?a la claseCriteriay los delega ascopeda nivel de clase. Estos métodos utilizan la función de MongoDBcounten lugar de cargar los documentos en la memoria, lo que mejora el rendimiento cuando los documentos aún no han sido obtenidos. El siguiente ejemplo muestra cómo utilizar estos métodos:User.any? # Returns true if any user documents exist User.one? # Returns true if exactly one user document exists in the criteria User.many? # Returns true if more than one user document exists in the criteria Agrega el método
Criteria#to_mql, que devuelve la representación en lenguaje de consulta de MongoDB (MQL) de una consulta. Utilice este método para inspeccionar las consultas que genera Mongoid. El siguiente ejemplo devuelve el MQL para una consultaPerson:Person.where(age: { '$gt' => 18 }).to_mql Agrega el método
Criteria#eager_loadpara cargar asociaciones mediante una canalización de agregación. A diferencia deincludes,eager_loadrealiza una única consulta a la base de datos. Este método ofrece un mejor rendimiento en las asociacioneshas_manyyhas_and_belongs_to_many, así como en consultas que combinan varias asociacionesbelongs_toohas_one. Si se utilizaeager_loaden una asociación incrustada, Mongoid recurre aincludes. El siguiente ejemplo carga anticipadamente las asociacionesemployerypartnerpara personas activas:Person.where(active: true).eager_load(:employer, :partner) Agrega compatibilidad con MongoDB Vector Search. Defina un índice de MongoDB Vector Search mediante la
vector_fieldmacro o elvector_search_indexmétodo, y luego llamevector_searcha para consultar documentos semánticamente similares. Para obtener más información, consulte la descripción general de MongoDB Vector Search. El siguiente ejemplo define un índice de MongoDB Vector Search en unArticlemodelo y consulta documentos similares:class Article include Mongoid::Document vector_field :embedding, dimensions: 1536 end articles = Article.vector_search(query_vector, limit: 5) Agrega la
auto_embed_fieldmacro, que habilita la incrustación automática en la compatibilidad con MongoDB Vector Search. Mongoid utiliza el modelo de incrustación configurado para indexar automáticamente el campo. Para obtener más información, consulte la Guía de inicio rápido de MongoDB Vector Search en la documentación de MongoDB Vector Search. El siguiente ejemplo define un campo de incrustación automática y realiza consultas para artículos similares:class Article include Mongoid::Document auto_embed_field :body end articles = Article.auto_embed_search('machine learning', limit: 5) Agrega soporte para especificar el tipo de documento asociado al llamar a
build_<association>ocreate_<association>en asociacionesembeds_one,has_oneybelongs_to. El siguiente ejemplo crea unHeadlessRunnerpara una asociaciónJob:job = Job.create job.build_runner({ name: 'My Runner' }, HeadlessRunner) Agrega la opción de configuración
Mongoid.allow_short_circuit_queries. Cuando se establece entrue, una condición$inde nivel superior con una matriz vacía devuelve un resultado vacío sin consultar la base de datos. Esta opción está configurada por defecto enfalse. El siguiente ejemplo habilita la opción:Mongoid.allow_short_circuit_queries = true Document.in(ids: []) # Returns [], no database query issued Actualiza el comportamiento de las declaraciones de índices duplicados. Mongoid ahora ignora las declaraciones de índices que difieren solo en sus opciones, incluido el nombre del índice. Para permitir que se envíen al servidor declaraciones de índices casi idénticas, establezca
Mongoid.allow_duplicate_index_declarations = true.Se desaconseja el uso del método
Criteria#max_scan.Cambia el valor predeterminado de
Mongoid::Config.allow_reparenting_via_nested_attributesafalse. Establezca esta opción entruepara restaurar el comportamiento anterior. Esta opción se eliminará en Mongoid v10.Cambia el valor predeterminado de
Mongoid.autosave_saves_unchanged_documentsafalse. Establezca esta opción entruepara restaurar el comportamiento anterior. Esta opción se eliminará en Mongoid v10.
Novedades en 9.0.11
La versión 9.0.11 incluye las siguientes nuevas características:
allow_reparenting_via_nested_attributes Configuración
Mongoid v9.0.11 introduce la opción de configuración Mongoid::Config.allow_reparenting_via_nested_attributes. Esta opción controla si los registros has_many dependientes pueden ser reasignados a través de atributos anidados.
Esta opción tiene como valor predeterminado true, lo que conserva el comportamiento anterior. Para evitar el cambio de padre a través de atributos anidados, establezca esta opción en false:
Mongoid::Config.allow_reparenting_via_nested_attributes = false
En Mongoid v9.1, esta opción tendrá como valor predeterminado false. La opción se eliminará en Mongoid v10.
Comportamiento de guardado automático para subárboles sin cambios
Mongoid v9.0.11 introduce la opción de configuración Mongoid.autosave_saves_unchanged_documents. Esta opción controla si Mongoid guarda automáticamente todos los documentos en un subárbol de asociación cuando cualquier documento en el subárbol tiene autosave: true.
En versiones anteriores de Mongoid, las asociaciones con autosave: true hacían que Mongoid invocara #save en todos los documentos secundarios e invocara recursivamente todos los ganchos after_save correspondientes, independientemente de si esos documentos habían cambiado.
Esta opción está configurada por defecto en true, conservando el comportamiento anterior. Para guardar automáticamente solo los subárboles que contienen documentos modificados, configure esta opción en false:
Mongoid.autosave_saves_unchanged_documents = false
En Mongoid v9.1, esta opción tendrá como valor predeterminado false. La opción se eliminará en Mongoid v10.
Soporte para Ruby 4.0
Mongoid v9.0.11 añade soporte oficial para Ruby 4.0.
Novedades en 9.0.7
Advertencia
cambio disruptivo
La versión 9.0.7 incluye cambios disruptivos.
La versión 9.0.7 incluye los siguientes cambios:
Una versión anterior de Mongoid corrigió un error en el que las devoluciones de llamada secundarias que dependían del estado principal ya no se invocaban si el elemento secundario no había cambiado. Debido a que la corrección introdujo una regresión de rendimiento, esta versión de parche es una restauración de la funcionalidad anterior. Las devoluciones de llamada de los hijos ahora solo se invocan si el propio hijo ha cambiado. Esto introduce cambios disruptivos para las aplicaciones que dependen de que se invoquen funciones de retorno en elementos secundarios no modificados (por ejemplo, cuando una función de retorno secundaria depende de que el elemento principal haya cambiado de estado).
El siguiente ejemplo de código muestra cómo invocar devoluciones de llamada de hijos en respuesta a cambios en los padres:
class Parent include Mongoid::Document has_many :children after_save { children.each(&:parent_changed_callback) } end class Child include Mongoid::Document belongs_to :parent def parent_changed_callback # ... end end
Novedades en 9.0
La versión 9.0 incluye las siguientes nuevas funcionalidades, mejoras y correcciones:
Railsmdb
Junto con el lanzamiento de Mongoid v9.0, railsmdb, una utilidad de línea de comandos para crear, actualizar, gestionar y mantener aplicaciones Rails, está generalmente disponible.
railsmdb facilita el trabajo con MongoDB desde la línea de comandos mediante generadores comunes con los que los desarrolladores de Ruby on Rails ya están familiarizados.
Por ejemplo, puedes usar railsmdb para generar stubs para nuevos modelos de Mongoid:
bin/railsmdb generate model person
Esto creará un nuevo modelo en app/models/person.rb:
class Person include Mongoid::Document include Mongoid::Timestamp end
Puedes especificar los campos del modelo:
bin/railsmdb generate model person name:string birth:date
class Person include Mongoid::Document include Mongoid::Timestamp field :name, type: String field :birth, type: Date end
Puedes indicar al generador que convierta el nuevo modelo en una subclase de otro, pasando la opción --parent:
bin/railsmdb generate model student --parent=person
class Student < Person include Mongoid::Timestamp end
Si necesitas almacenar tus modelos en una colección diferente a la que se pueda inferir del nombre del modelo, puedes especificar --collection:
bin/railsmdb generate model course --collection=classes
class Course include Mongoid::Document include Mongoid::Timestamp store_in collection: 'classes' end
Para más información, consulta el repositorio mongoid-railsmdb en GitHub.
Eliminación del soporte para Ruby 2.6 y JRuby 9.3
Mongoid v9.0 requiere Ruby 2.7 o superior o JRuby 9.4. No se admite versiones anteriores de Ruby y JRuby.
Eliminación del Soporte para Rails 5
Mongoid v9.0 requiere Rails 6.0 o una versión más reciente. No se admiten versiones anteriores de Rails.
Eliminar la clase obsoleta Mongoid::Errors::InvalidStorageParent
La clase obsoleta Mongoid::Errors::InvalidStorageParent ha sido eliminada.
around_* Las devoluciones de llamada para documentos incrustados se ignoran de forma predeterminada.
Mongoid8 v.x y versiones anteriores permiten a los usuarios definir around_* funciones de devolución de llamada (callbacks) para documentos incrustados. A partir de9.0 la versión v, estas funciones se ignoran y no se ejecutan por defecto. Si se definen dichas funciones, se mostrará una advertencia en la consola.
Si desea restaurar el comportamiento anterior, puede establecer Mongoid.around_callbacks_for_embeds a true en su aplicación.
Nota
Habilitar las around_* funciones de retorno para documentos incrustados no es recomendado, ya que puede causar excepciones SystemStackError cuando un documento tiene muchos documentos incrustados. Consulta MONGOID-5658 para obtener más detalles.
for_js Este método está obsoleto
El método for_js está obsoleto y se eliminará en Mongoid v10.0.
Eliminación de opciones obsoletas
Cambio disruptivo: Las siguientes opciones de configuración se eliminan en Mongoid v9.0. Por favor, asegúrate de eliminar todas las referencias a estos elementos de tu aplicación. Si estabas utilizando config.load_defaults 8.1 antes de la actualización, no experimentarás ningún cambio de comportamiento. Consulte las notas de versión anteriores para entender el significado de cada opción.
:use_activesupport_time_zone:broken_aggregables:broken_alias_handling:broken_and:broken_scoping:broken_updates:compare_time_by_ms:legacy_attributes:legacy_pluck_distinct:legacy_triple_equals:object_id_as_json_oid:overwrite_chained_operators
Además, se ha descartado el soporte para config.load_defaults versiones v7.5 y anteriores (se debe usar al menos la versión v8.0).
Eliminación de funciones obsoletas
Cambio disruptivo: Se ha eliminado la siguiente funcionalidad obsoleta:
El módulo
Mongoid::QueryCacheha sido eliminado. Por favor, reemplace cualquier uso de 1-por-1 porMongo::QueryCache. El métodoMongoid::QueryCache#clear_cachedebería ser reemplazado porMongo::QueryCache#clear. Todos los demás métodos y submódulos tienen el mismo nombre.Object#blank_criteria?método eliminado (anteriormente obsoleto).Document#as_json :compactla opción se elimina. Llama a`#compacten el objetoHashresultante en su lugar.La clase obsoleta
Mongoid::Errors::InvalidStorageParentha sido eliminada.
Obtener y establecer variables Thread-Local
Nuevo en la versión 9.0.3.
Puede usar los métodos Mongoid::Threaded.get y Mongoid::Threaded.set para consultar y modificar variables locales del hilo. Para aprender cuándo utilizar estos métodos, consulta la sección Variables de hilo local de la guía de Callbacks.
Configuración de verificación de índice
Nuevo en la versión 9.0.7.
Puedes usar la opción de configuración Mongoid.allow_duplicate_index_declarations para enviar la verificación de índices al servidor. Si se declara un índice duplicado, el servidor generará un error. Para conocer más, consulte la sección Opciones de configuración de la guía de Configuración de la aplicación.
touch El método borra el estado cambiado
En Mongoid v8.x y en versiones anteriores, el método touch deja los modelos en el estado modificado:
# v8.x behaviour band = Band.create! band.touch band.changed? # => true band.changes # => {"updated_at"=>[2023-01-30 13:12:57.477191135 UTC, 2023-01-30 13:13:11.482975646 UTC]}
A partir de v9.0, Mongoid ahora borra correctamente el estado de cambio después de usar el método touch.
# v9.0 behavior band = Band.create! band.touch band.changed? # => false band.changes # => {}
Modo sandbox para la consola de Rails
Mongoid ahora soporta modo sandbox para la consola de Rails. Si la consola Rails se inició con la bandera --sandbox, Mongoid inicia una transacción en el cliente :default antes de abrir la consola. Esta transacción no será confirmada. Por lo tanto, todos los comandos ejecutados en la consola usando el cliente :default no se guardarán en la base de datos.
Nota
Si ejecutas comandos en el modo sandbox utilizando cualquier otro cliente que no sea el por defecto, estos cambios se persistirán como de costumbre.
Nueva API de transacciones
Mongoid 9.0 presenta una nueva API de transacciones inspirada en Active Record:
Band.transaction do Band.create(title: 'Led Zeppelin') end band = Band.create(title: 'Deep Purple') band.transaction do band.active = false band.save! end
Para obtener más información, consulte la guía Transacciones y sesiones.
Los documentos incrustados siempre usan el contexto de persistencia de los documentos principales
Mongoid v8.x y versiones anteriores permiten al usuario especificar el contexto de persistencia para un documento incrustado (utilizando la macro store_in). En Mongoid v9.0 estos ajustes se ignoran para los documentos incrustados. Un documento incrustado ahora siempre utiliza el contexto de persistencia de su documento principal.
Compatibilidad para pasar valores sin procesar a las consultas
Al realizar consultas, ahora es posible omitir la lógica de conversión de tipo de Mongoid utilizando la clase contenedor Mongoid::RawValue. Esto puede ser útil cuando los datos legados en la base de datos son de un tipo diferente al de la definición del campo.
class Person include Mongoid::Document field :age, type: Integer end # Query for the string "42", not the integer 42 Person.where(age: Mongoid::RawValue("42"))
Levantar Error de AttributeNotLoaded al acceder a campos omitidos de la proyección de la query
Cuando intente acceder a un campo en una instancia del modelo que quedó excluido con los métodos de proyección de only o without al cargarse la instancia, Mongoid producirá ahora un error Mongoid::Errors::AttributeNotLoaded.
Band.only(:name).first.label #=> raises Mongoid::Errors::AttributeNotLoaded Band.without(:label).first.label = 'Sub Pop Records' #=> raises Mongoid::Errors::AttributeNotLoaded
En versiones anteriores de Mongoid, las mismas condiciones generarían un ActiveModel::MissingAttributeError. Por favor, revisa tu código en busca de cualquier uso específico de Mongoid de esta clase y cámbialo por Mongoid::Errors::AttributeNotLoaded. Nota además que AttributeNotLoaded hereda de Mongoid::Errors::MongoidError, mientras que ActiveModel::MissingAttributeError no lo hace.
Use la zona horaria configurada para convertir Date a Time en consultas
Al consultar un campo de hora usando un valor de fecha, Mongoid ahora considera correctamente Time.zone para realizar la conversión de tipos.
class Magazine include Mongoid::Document field :published_at, type: Time end Time.zone = 'Asia/Tokyo' Magazine.gte(published_at: Date.parse('2022-09-26')) #=> will return all results on or after Sept 26th, 2022 # at 0:00 in Asia/Tokyo time zone.
En versiones anteriores de Mongoid, el código anterior ignoraba el Time.zone (independientemente de la configuración :use_activesupport_time_zone ahora eliminada) y siempre usaba la zona horaria del sistema para realizar la conversión de tipo.
Tenga en cuenta que en versiones anteriores de Mongoid, el cambio de tipo de Date a Time durante las operaciones de persistencia ya estaba utilizando correctamente la zona horaria.
touch El método en documento incrustado gestiona correctamente la opción touch: false
Cuando se activa la opción touch: false en una relación de tipo embedded_in, llamar al método touch en un documento hijo incrustado no activará touch en su documento padre.
class Address include Mongoid::Document include Mongoid::Timestamps embedded_in :mall, touch: false end class Mall include Mongoid::Document include Mongoid::Timestamps embeds_many :addresses end mall = Mall.create! address = mall.addresses.create! address.touch #=> updates address.updated_at but not mall.updated_at
Además, el método touch ha sido optimizado para realizar una operación de persistencia por documento padre, incluso al usar múltiples niveles de documentos incrustados anidados.
embedded_in Las asociaciones por defecto touch: true
Actualizar un subdocumento embebido ahora modificará automáticamente el padre, a menos que establezcas explícitamente touch: false en la relación:
class Address include Mongoid::Document include Mongoid::Timestamps embedded_in :mall, touch: false end
Para todas las demás asociaciones, el valor por defecto sigue siendo touch: false.
Opción por defecto invertida para :replace en upsert
Mongoid v8.1 se añadió la opción :replace al método upsert. Esta opción se utilizó para especificar si el documento existente debía actualizarse o reemplazarse.
Mongoid v9.0 revierte el valor por defecto de este indicador de true a false. Esto significa que, por defecto, Mongoid v9.0 actualiza el documento existente y no lo reemplaza.
Inmutabilidad del campo _id reforzada
Antes de Mongoid v9.0, modificar el campo _id se comportaba de manera inconsistente dependiendo de si el documento era de nivel superior o incrustado, y según cómo se realizaba la actualización. En v9.0, cambiar el campo _id ahora generará una excepción cuando se guarde el documento, si el documento se había guardado previamente.
Mongoid 9.0 también introduce una nueva funcionalidad de banderas, immutable_ids, que por defecto está en true.
Mongoid::Config.immutable_ids = true
Cuando se establece en false, se restaura el comportamiento más antiguo y poco consistente.
Soporte para alias de campo en las opciones de índice
Se ha agregado soporte para el uso de nombres de campos con alias en las siguientes opciones de la macro index: partial_filter_expression, weights, wildcard_projection.
class Person include Mongoid::Document field :a, as: :age index({ age: 1 }, { partial_filter_expression: { age: { '$gte' => 20 } }) end
Nota
La expansión de los alias de nombres de campos en las opciones de índice, como partial_filter_expression, se realiza de acuerdo con el comportamiento del servidor MongoDB 6.0. Versiones futuras del servidor podrían cambiar la manera en que interpretan estas opciones, y la funcionalidad de Mongoid quizás no sea compatible con esos cambios.
Campos BSON 5 y BSON::Decimal128
Cuando BSON 4 o anteriores están presentes, cualquier campo declarado como BSON::Decimal128 devolverá un valor de BSON::Decimal128. Sin embargo, cuando BSON 5 está presente, cualquier campo declarado como BSON::Decimal128 devolverá un valor BigDecimal por defecto.
class Model include Mongoid::Document field :decimal_field, type: BSON::Decimal128 end # under BSON <= 4 Model.first.decimal_field.class #=> BSON::Decimal128 # under BSON >= 5 Model.first.decimal_field.class #=> BigDecimal
Si necesita valores literales BSON::Decimal128 con BSON 5, puede indicar a Mongoid que permita campos literales BSON::Decimal128:
Model.first.decimal_field.class #=> BigDecimal Mongoid.allow_bson5_decimal128 = true Model.first.decimal_field.class #=> BSON::Decimal128
Nota
La opción allow_bson5_decimal128 solo tiene efecto bajo BSON 5 y posteriores. El BSON 4 y las versiones anteriores ignoran por completo la configuración.
Gestión del índice de búsqueda de MongoDB Atlas
Cuando se conecta a MongoDB Atlas, Mongoid ahora permite crear y remover índices de búsqueda. Puedes hacer esto mediante programación, a través de la API Mongoid::SearchIndexable :
class SearchablePerson include Mongoid::Document search_index { ... } # define the search index here end # create the declared search indexes; this returns immediately, but the # search indexes may take several minutes before they are available. SearchablePerson.create_search_indexes # query the available search indexes SearchablePerson.search_indexes.each do |index| # ... end # remove all search indexes from the model's collection SearchablePerson.remove_search_indexes
Si no estás conectado a MongoDB Atlas, las definiciones de los índices de búsqueda se omiten. Al intentar crear, enumerar o remover índices de búsqueda, se producirá un error.
También hay tareas rake disponibles, para mayor comodidad:
# create search indexes for all models; waits for indexes to be created # and shows progress on the terminal. $ rake mongoid:db:create_search_indexes # as above, but returns immediately and lets the indexes be created in the # background $ rake WAIT_FOR_SEARCH_INDEXES=0 mongoid:db:create_search_indexes # removes search indexes from all models $ rake mongoid:db:remove_search_indexes
Retiro de Time.configured
Time.configured devolvió el objeto de tiempo que envolvía la zona horaria configurada o la clase estándar Time de Ruby. Esto permitía query un valor de tiempo incluso si no se había configurado una zona horaria.
Mongoid ahora requiere que establezcas una zona horaria si planeas realizar cualquier acción relacionada con valores de tiempo (incluyendo el uso de marcas de tiempo en tus documentos). Se debe reemplazar cualquier uso de Time.configured por Time.zone.
# before: puts Time.configured.now # after: puts Time.zone.now # or, better for finding the current Time specifically: puts Time.current
Si no configuras una zona horaria, verás errores en tu código relacionados con los valores de nil. Si utiliza Rails, la zona horaria predeterminada ya está configurada en UTC. Si no está utilizando Rails, puede establecer una zona horaria al inicio de su programa de la siguiente manera:
Time.zone = 'UTC'
Esto establecerá la zona horaria en UTC. Puedes ver todos los nombres de zonas horarias disponibles ejecutando el siguiente comando:
$ ruby -ractive_support/values/time_zone \ -e 'puts ActiveSupport::TimeZone::MAPPING.keys'
Registros Recordar Contexto de Persistencia de Creación
Considera el siguiente código:
record = Model.with(collection: 'other_collection') { Model.first } record.update(field: 'value')
Antes de Mongoid v9.0, el código anterior fallaba silenciosamente al ejecutar la actualización, porque las opciones de almacenamiento (en este caso, la especificación de una colección alternativa para el modelo) no serían recordadas por el registro. Por lo tanto, el registro se cargaría desde other_collection, pero al actualizarse intentaría buscar y actualizar el documento en la colección predeterminada para Model. Para que esto funcione, tendrías que haber especificado la colección explícitamente para cada actualización.
A partir de Mongoid v9.0, los registros que se creen o carguen con opciones de almacenamiento explícitas recordarán esas opciones (incluidos un cliente con nombre, una base de datos diferente o una colección diferente).
Si necesitas la versión heredada (anterior a v9.0) comportamiento, puedes activarlo con la siguiente bandera:
Mongoid.legacy_persistence_context_behavior = true
Esta bandera viene por defecto como falsa en Mongoid v9.0.