Overview
Esta guía te muestra cómo usar Laravel MongoDB para definir y personalizar modelos de Laravel Eloquent. Puedes usar estos modelos para trabajar con datos de MongoDB mediante el mapeador objeto-relacional (ORM) de Laravel Eloquent.
Las siguientes secciones explican cómo agregar comportamientos ORM de Laravel Eloquent a los modelos de Laravel MongoDB:
Definir una clase de modelo Eloquent demuestra cómo crear una clase de modelo.
Extiende el modelo autenticable muestra cómo definir MongoDB como el proveedor de usuarios de autenticación.
Personalizar una clase de modelo Eloquent explica varias personalizaciones de clases de modelo.
Ampliar clases de modelos de terceros explica cómo hacer que las clases de modelos de terceros sean compatibles con MongoDB.
Especificar comportamiento de poda muestra cómo eliminar periódicamente modelos que ya no necesita.
Crear un esquema de modelo versionado muestra cómo implementar la versionado del esquema del modelo.
Define una clase de modelo en Eloquent
Los modelos Eloquent son clases que representan sus datos. Incluyen métodos que realizan operaciones de base de datos como inserciones, actualizaciones y eliminaciones.
Para declarar un modelo Laravel MongoDB, cree una clase en el app/Models
directorio de su aplicación Laravel que extiende MongoDB\Laravel\Eloquent\Model como se muestra en el siguiente ejemplo de código:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { }
De manera predeterminada, el modelo utiliza el nombre de la base de datos MongoDB establecido en la configuración config/database.php de su aplicación Laravel y la forma plural en mayúsculas y minúsculas del nombre de la clase de su modelo para la colección.
Este modelo se almacena en la colección MongoDB planets.
Tip
Como alternativa, usa la artisan consola para generar la clase del modelo y cambia la Illuminate\Database\Eloquent\Model importación MongoDB\Laravel\Eloquent\Model a. Para obtener más información sobre la artisan consola, consulta la consola Artisan en la documentación de Laravel.
Para aprender a especificar el nombre de la base de datos que utiliza su aplicación Laravel, Configure su conexión MongoDB.
Ampliar el modelo autenticable
Para configurar MongoDB como proveedor de usuarios de Laravel, puede extender la clase MongoDB\Laravel\Auth\User de Integración de Laravel. El siguiente ejemplo de código muestra cómo extender esta clase:
namespace App\Models; use MongoDB\Laravel\Auth\User as Authenticatable; class User extends Authenticatable { }
Para obtener más información sobre cómo personalizar un proveedor de usuarios de autenticación de Laravel, consulte Agregar proveedores de usuarios personalizados en la documentación de Laravel.
Personalizar una clase de modelo Eloquent
Esta sección muestra cómo realizar las siguientes personalizaciones del comportamiento del modelo Eloquent:
Cambiar el nombre de la colección de modelos
De forma predeterminada, el modelo usa el plural de la clase del modelo (con mayúscula inicial y minúscula). Para cambiar el nombre de la colección que el modelo usa para recuperar y guardar datos en MongoDB, anule la propiedad $table de la clase del modelo.
Nota
Recomendamos utilizar el comportamiento de nombres de colección predeterminado para mantener sencillas las asociaciones entre modelos y colecciones.
El siguiente ejemplo especifica el nombre de la colección MongoDB personalizada, celestial_body, para la clase Planet:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { protected $table = 'celestial_body'; }
Sin sobreescribir la propiedad $table, este modelo se asigna a la colección planets. Con la propiedad anulada, la clase de ejemplo almacena el modelo en la colección celestial_body.
Cambiar el campo de clave principal
Para personalizar el campo de clave principal del modelo que identifica de forma única un documento MongoDB, anule la propiedad $primaryKey de la clase del modelo.
De forma predeterminada, el modelo utiliza el controlador PHP MongoDB para generar ObjectID únicos para cada documento que inserta su aplicación Laravel.
El siguiente ejemplo especifica el campo name como clave principal para la clase Planet:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { protected $primaryKey = 'name'; }
Para obtener más información sobre el comportamiento de la clave principal y las opciones de personalización, consulte Claves primarias de Eloquent en la documentación de Laravel.
Para obtener más información sobre el _id campo, los ObjectID y la estructura del documento MongoDB,consulte Documentos en el manual del servidor.
Habilitar eliminaciones suaves
Eloquent incluye una función de eliminación temporal que modifica el comportamiento del método delete() en un modelo. Cuando se habilita la eliminación temporal en un modelo, el método delete() marca un documento como eliminado en lugar de eliminarlo de la base de datos. Establece una marca de tiempo en el campo deleted_at para excluirlo automáticamente de las operaciones de recuperación.
Para habilitar eliminaciones suaves en una clase, agregue el rasgo Illuminate\Database\Eloquent\SoftDeletes como se muestra en el siguiente ejemplo de código:
namespace App\Models; use Illuminate\Database\Eloquent\SoftDeletes; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { use SoftDeletes; }
Para obtener más información sobre los métodos que puede ejecutar en modelos con eliminaciones suaves habilitadas, consulte Eliminación suave de Eloquent en la documentación de Laravel.
Tipos de datos de conversión
Eloquent permite convertir los tipos de datos de los atributos del modelo antes de almacenarlos o recuperarlos mediante un asistente de conversión. Este asistente es una alternativa práctica para definir métodos de acceso y mutación equivalentes en el modelo.
En el siguiente ejemplo, el asistente de conversión convierte el discovery_dt atributo de modelo, almacenado en MongoDB como un tipo MongoDB\\BSON\\UTCDateTime, al tipo Laravel.datetime
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { protected $casts = [ 'discovery_dt' => 'datetime', ]; }
Tip
Conversiones en Laravel 11
A partir de Laravel 11, puedes definir un método casts() para especificar conversiones de tipos de datos en lugar de usar el atributo $casts. El siguiente código realiza la misma conversión que el ejemplo anterior usando un método casts():
protected function casts(): array { return [ 'discovery_dt' => 'datetime', ]; }
Para obtener más información, consulte Conversión de atributos en la documentación de Laravel.
Esta conversión permite usar la clase DateTime de PHP para trabajar con fechas en este campo. El siguiente ejemplo muestra una consulta de Laravel que utiliza el ayudante de conversión del modelo para consultar planetas con un discovery_dt valor de de hace menos de tres años:
Planet::where( 'discovery_dt', '>', new DateTime('-3 years'))->get();
Nota
Clase de datación por carbono
Comenzando en Laravel MongoDB v5.0, Los valores BSON UTCDateTime en MongoDB se devuelven como clases de fecha Carbon en los resultados de las queries. La integración de Laravel aplica la zona horaria por defecto al realizar esta conversión.
Para obtener más información sobre los tipos de datos de MongoDB, consulte Tipos BSON en el manual del servidor.
Para obtener más información sobre el asistente de conversión de Laravel y los tipos admitidos, consulte Conversión de atributos en la documentación de Laravel.
Personalizar la asignación masiva
Eloquent permite crear varios modelos y sus datos de atributos pasando una matriz de datos al método de modelo create(). Este proceso de inserción de múltiples modelos se denomina asignación masiva.
La asignación masiva puede ser una forma eficiente de crear múltiples modelos. Sin embargo, puede exponer una vulnerabilidad de seguridad explotable. Los datos de los campos podrían contener actualizaciones que otorguen permisos o accesos no autorizados.
Eloquent proporciona las siguientes características para proteger sus datos de vulnerabilidades de asignación masiva:
$fillableContiene los campos que se pueden escribir en una asignación masiva$guardedContiene los campos que se ignoran en una asignación masiva
Importante
Recomendamos usar en $fillable lugar de $guarded para protegerse contra vulnerabilidades. Para obtener más información sobre esta recomendación, consulte el artículo "Versión de seguridad: Laravel,.6.18.35 7.24"0 en el sitio web de Laravel.
En el siguiente ejemplo, el modelo permite la asignación masiva de los campos mediante el atributo $fillable:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { protected $fillable = [ 'name', 'gravitational_force', 'diameter', 'moons', ]; }
El siguiente ejemplo de código muestra la asignación masiva del modelo Planet:
$planets = [ [ 'name' => 'Earth', 'gravitational_force' => 9.8, 'day_length' => '24 hours' ], [ 'name' => 'Mars', 'gravitational_force' => 3.7, 'day_length' => '25 hours' ], ]; Planet::create($planets);
Los modelos guardados en la base de datos contienen solo los campos name y gravity ya que day_length se omite del atributo $fillable.
Para aprender cómo cambiar el comportamiento al intentar completar un campo omitido de la $fillable matriz, consulte Excepciones de asignación masiva en la documentación de Laravel.
Ampliar clases de modelos de terceros
Puedes usar la integración de Laravel para extender una clase de modelo de terceros incluyendo el atributo DocumentModel al definirla. Al incluir este atributo, puedes hacer que la clase de terceros sea compatible con MongoDB.
Cuando aplica el rasgo DocumentModel a una clase de modelo, debe establecer la propiedad $keyType en 'string' ya que la integración de Laravel convierte los valores ObjectId de MongoDB al tipo string.
Ejemplo de clase extendida
Este ejemplo crea una clase de modelo Planet que extiende la clase CelestialBody de un paquete llamado ThirdPartyPackage. La clase Post incluye el atributo DocumentModel y define propiedades como $primaryKey y $keyType:
namespace App\Models; use MongoDB\Laravel\Eloquent\DocumentModel; use ThirdPartyPackage\CelestialBody; class Planet extends CelestialBody { use DocumentModel; protected $fillable = ['name', 'diameter']; protected $keyType = 'string'; }
Después de definir su clase, puede realizar operaciones de MongoDB como de costumbre.
Tip
Para ver otro ejemplo que utiliza el DocumentModel rasgo, consulte la sección Laravel Sanctum de la guía de autenticación de usuario.
Especificar el comportamiento de poda
Eloquent te permite especificar criterios para eliminar periódicamente los datos del modelo que ya no necesitas. Al programar o ejecutar el comando model:prune, Laravel llama al método prunable() en todos los modelos que importan los rasgos Prunable y MassPrunable para que coincidan con los modelos que se eliminarán.
Para usar esta funcionalidad con modelos que utilizan MongoDB como base de datos, añade la importación apropiada a tu modelo:
Illuminate\Database\Eloquent\PrunableOpcionalmente, realiza un paso de limpieza antes de eliminar un modelo que coincide con los criterios.MongoDB\Laravel\Eloquent\MassPrunableElimina los modelos que coinciden con los criterios sin obtener los datos del modelo.
Nota
Al habilitar eliminaciones suaves en un modelo podable en masa, debe importar los siguientes paquetes Laravel MongoDB:
Illuminate\Database\Eloquent\SoftDeletesMongoDB\Laravel\Eloquent\MassPrunable
Para obtener más información sobre la función de poda, consulte Modelos de poda en la documentación de Laravel.
Ejemplo de podabilidad
La siguiente clase podable incluye un método prunable() que coincide con los modelos que la acción de poda elimina y un método pruning() que se ejecuta antes de eliminar un modelo coincidente:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; use Illuminate\Database\Eloquent\Prunable; class Planet extends Model { use Prunable; public function prunable() { // matches models in which the solar_system field contains a null value return static::whereNull('solar_system'); } protected function pruning() { // Add cleanup actions, such as logging the Planet 'name' attribute } }
Ejemplo "Mass Prunable"
La siguiente clase podable en masa incluye un método prunable() que coincide con los modelos que la acción de poda elimina:
namespace App\Models; use MongoDB\Laravel\Eloquent\MassPrunable; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { use MassPrunable; public function prunable() { // matches models in which the gravitational_force field contains // a value greater than 0.5 return static::where('gravitational_force', '>', 0.5); } }
Crear un esquema de modelo versionado
Puede implementar un patrón de control de versiones de esquema en su aplicación mediante el atributo HasSchemaVersion en un modelo Eloquent. Puede optar por implementar una versión de esquema para organizar o estandarizar una colección que contenga datos con diferentes esquemas.
Tip
Para obtener más información sobre versionado de esquemas, consulta el tutorial Modelar datos para versionado de esquemas en el Manual de servidor.
Para usar esta función con modelos que usan MongoDB como base de datos, agregue la importación MongoDB\Laravel\Eloquent\HasSchemaVersion a su modelo. Luego, establezca la constante SCHEMA_VERSION en 1 para establecer la primera versión del esquema en su colección. Si su colección evoluciona para contener varios esquemas, puede actualizar el valor de la constante SCHEMA_VERSION en las clases de modelo posteriores.
Al crear su modelo, puede definir el método migrateSchema() para especificar una migración a la versión actual del esquema al recuperar un modelo. En este método, puede especificar los cambios que se realizarán en un modelo anterior para actualizarlo y que coincida con la versión actual del esquema.
Al guardar un modelo sin una versión de esquema especificada, el rasgo HasSchemaVersion asume que sigue la última versión del esquema. Al recuperar un modelo sin el campo schema_version, el rasgo asume que su versión de esquema es 0 y realiza la migración.
Ejemplo de control de versiones del esquema
En esta situación de ejemplo, estás trabajando con una colección que primero fue modelada por la siguiente clase:
namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { protected $fillable = ['name', 'type']; }
Ahora, desea implementar una nueva versión del esquema en la colección. Puede definir la nueva clase de modelo con el siguiente comportamiento:
Implementa el rasgo
HasSchemaVersiony establece elSCHEMA_VERSIONactual en2Define el método
migrateSchema()para migrar modelos en los que la versión del esquema es menor que2para tener un campogalaxyque tenga un valor de'Milky Way'
namespace App\Models; use MongoDB\Laravel\Eloquent\HasSchemaVersion; use MongoDB\Laravel\Eloquent\Model; class Planet extends Model { use HasSchemaVersion; public const SCHEMA_VERSION = 2; protected $fillable = ['name', 'type', 'galaxy']; /** * Migrate documents with a lower schema version to the most current * schema when inserting new data or retrieving from the database. */ public function migrateSchema(int $fromVersion): void { if ($fromVersion < 2) { $this->galaxy = 'Milky Way'; } } }
En el documento "WASP-39 b" del siguiente código, el valor del campo schema_version es menor que 2. Al recuperar el documento, la integración de Laravel agrega el campo galaxy y actualiza la versión del esquema a la versión actual, 2.
El documento "Saturn" no contiene el campo schema_version, por lo que la integración de Laravel le asigna la versión del esquema actual al guardarlo.
Finalmente, el código recupera los modelos de la colección para demostrar los cambios:
// Simulates a document in the collection with schema version 1 Planet::insert([ [ 'name' => 'WASP-39 b', 'type' => 'gas', 'schema_version' => 1, ], ]); // Saves a document with no specified schema version $saturn = Planet::create([ 'name' => 'Saturn', 'type' => 'gas', ]); // Retrieves both models from the collection $planets = Planet::where('type', 'gas') ->get();
[ { "_id": ..., "name": "WASP-39 b", "type": "gas", "galaxy": "Milky Way", "schema_version": 2, }, { "_id": ..., "name": "Saturn", "type": "gas", "schema_version": 2, } ]