Join us at MongoDB.local London on 7 May to unlock new possibilities for your data. Use WEB50 to save 50%.
Register now >
Docs Menu
Docs Home
/ /

Relaciones de modelos en Eloquent

Al usar una base de datos relacional, el ORM de Eloquent almacena los modelos como filas en tablas que corresponden a las clases del modelo. Al usar MongoDB, la integración de Laravel almacena los modelos como documentos en colecciones que corresponden a las clases del modelo.

Para definir una relación, agregue una función a la clase del modelo que llame al método de relación correspondiente. Esta función permite acceder al modelo relacionado como una propiedad dinámica. Una propiedad dinámica permite acceder al modelo relacionado utilizando la misma sintaxis que se utiliza para acceder a una propiedad del modelo.

Las siguientes secciones describen las relaciones específicas de Laravel Eloquent y MongoDB disponibles en la Integración de Laravel y muestran ejemplos de cómo definirlas y utilizarlas:

  • Relación uno a uno, creada utilizando el hasOne() el método y su inverso, belongsTo()

  • Una relación de uno a muchos, creada al utilizar el hasMany() y su inverso, belongsTo()

  • Relación muchos a muchos, creada utilizando el método belongsToMany()

  • Patrón de documento incrustado, una relación específica de MongoDB que puede representar una relación uno a uno o uno a muchos, creada mediante el uso del método embedsOne() o embedsMany()

  • Relaciones entre bases de datos, necesarias cuando se desea crear relaciones entre modelos MongoDB y SQL

Una relación uno a uno entre modelos consiste en un registro de modelo relacionado con exactamente otro tipo de registro de modelo.

Cuando agregas una relación uno a uno, Eloquent te permite acceder al modelo mediante una propiedad dinámica y almacena el ID del documento del modelo en el modelo relacionado.

En Laravel MongoDB, puedes definir una relación uno a uno utilizando el método hasOne() o el método belongsTo().

Cuando agrega la inversa de la relación mediante el método belongsTo(), Eloquent le permite acceder al modelo mediante una propiedad dinámica, pero no agrega ningún campo.

Para obtener más información sobre las relaciones uno a uno, consulte Uno a uno en la documentación de Laravel.

La siguiente clase de ejemplo muestra cómo definir una relación uno-a-uno HasOne entre un modelo Planet y Orbit usando el método hasOne():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\HasOne;
class Planet extends Model
{
protected $connection = 'mongodb';
public function orbit(): HasOne
{
return $this->hasOne(Orbit::class);
}
}

La siguiente clase de ejemplo muestra cómo definir la relación inversa BelongsTo entre Orbit y Planet mediante el método belongsTo():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\BelongsTo;
class Orbit extends Model
{
protected $connection = 'mongodb';
public function planet(): BelongsTo
{
return $this->belongsTo(Planet::class);
}
}

El siguiente código de ejemplo muestra cómo crear una instancia de un modelo para cada clase y añadir la relación entre ellas. Haz clic en el VIEW OUTPUT Botón para ver los datos creados al ejecutar el código:

$planet = new Planet();
$planet->name = 'Earth';
$planet->diameter_km = 12742;
$planet->save();
$orbit = new Orbit();
$orbit->period = 365.26;
$orbit->direction = 'counterclockwise';
$planet->orbit()->save($orbit);
// Document in the "planets" collection
{
_id: ObjectId('65de67fb2e59d63e6d07f8b8'),
name: 'Earth',
diameter_km: 12742,
// ...
}
// Document in the "orbits" collection
{
_id: ObjectId('65de67fb2e59d63e6d07f8b9'),
period: 365.26,
direction: 'counterclockwise',
planet_id: '65de67fb2e59d63e6d07f8b8',
// ...
}

El siguiente código de ejemplo muestra cómo acceder a los modelos relacionados utilizando las propiedades dinámicas según se definen en las clases de ejemplo:

$planet = Planet::first();
$relatedOrbit = $planet->orbit;
$orbit = Orbit::first();
$relatedPlanet = $orbit->planet;

Una relación de uno a muchos entre modelos consiste en un modelo que es el padre y uno o más registros de modelos secundarios relacionados.

Al añadir un método de relación uno a muchos, Eloquent permite acceder al modelo mediante una propiedad dinámica y almacena el ID de documento del modelo padre en cada documento de modelo secundario.

En Laravel MongoDB, puedes definir una relación de uno a muchos agregando el método hasMany() en la clase principal y, opcionalmente, el método belongsTo() en la clase secundaria.

Cuando sumas la inversa de la relación usando el método belongsTo(), Eloquent te permite acceder al modelo principal usando una propiedad dinámica sin añadir ningún campo.

Para aprender más sobre las relaciones de uno a muchos, consulta Uno a Muchos en la documentación de Laravel.

La siguiente clase de ejemplo muestra cómo definir una relación de uno a muchos HasMany entre un modelo padre Planet y un modelo hijo Moon utilizando el método hasMany():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\HasMany;
class Planet extends Model
{
protected $connection = 'mongodb';
public function moons(): HasMany
{
return $this->hasMany(Moon::class);
}
}

La siguiente clase de ejemplo muestra cómo definir la relación inversa BelongsTo entre un modelo hijo Moon y el modelo padre Planet utilizando el método belongsTo():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\BelongsTo;
class Moon extends Model
{
protected $connection = 'mongodb';
public function planet(): BelongsTo
{
return $this->belongsTo(Planet::class);
}
}

El siguiente código de ejemplo muestra cómo instanciar un modelo para cada clase y agregar la relación entre ellas. Haz clic en el botón VIEW OUTPUT para ver los datos creados al ejecutar el código:

$planet = new Planet();
$planet->name = 'Jupiter';
$planet->diameter_km = 142984;
$planet->save();
$moon1 = new Moon();
$moon1->name = 'Ganymede';
$moon1->orbital_period = 7.15;
$moon2 = new Moon();
$moon2->name = 'Europa';
$moon2->orbital_period = 3.55;
$planet->moons()->save($moon1);
$planet->moons()->save($moon2);
// Parent document in the "planets" collection
{
_id: ObjectId('65dfb0050e323bbef800f7b2'),
name: 'Jupiter',
diameter_km: 142984,
// ...
}
// Child documents in the "moons" collection
[
{
_id: ObjectId('65dfb0050e323bbef800f7b3'),
name: 'Ganymede',
orbital_period: 7.15,
planet_id: '65dfb0050e323bbef800f7b2',
// ...
},
{
_id: ObjectId('65dfb0050e323bbef800f7b4'),
name: 'Europa',
orbital_period: 3.55,
planet_id: '65dfb0050e323bbef800f7b2',
// ...
}
]

El siguiente código de ejemplo muestra cómo acceder a los modelos relacionados utilizando las propiedades dinámicas tal como se define en las clases de ejemplo.

$planet = Planet::first();
$relatedMoons = $planet->moons;
$moon = Moon::first();
$relatedPlanet = $moon->planet;

Una relación de muchos a muchos consiste en una relación entre dos tipos de modelos diferentes en la que, para cada tipo de modelo, una instancia del modelo puede estar relacionada con múltiples instancias del otro tipo.

En Laravel MongoDB, puedes definir una relación de muchos a muchos agregando el método belongsToMany() a ambas clases relacionadas.

Cuando defines una relación de muchos a muchos en una base de datos relacional, Laravel crea una tabla intermedia para rastrear las relaciones. Cuando utilizas la Integración de Laravel, se omite la creación de la tabla intermedia y se agregan los IDs de los documentos relacionados a un campo de documento derivado del nombre de la clase del modelo relacionado.

Tip

Dado que la integración de Laravel utiliza un campo de documento en lugar de una tabla dinámica, omita el parámetro de tabla dinámica del constructor belongsToMany() o configúrelo en null.

Para obtener más información sobre relaciones muchos a muchos en Laravel, consulte Muchos a muchos en la documentación de Laravel.

La siguiente sección muestra un ejemplo de cómo crear una relación de muchos a muchos entre clases de modelos.

La siguiente clase de ejemplo muestra cómo definir una relación de muchos a muchos BelongsToMany entre un modelo Planet y SpaceExplorer utilizando el método belongsToMany():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\BelongsToMany;
class Planet extends Model
{
protected $connection = 'mongodb';
public function visitors(): BelongsToMany
{
return $this->belongsToMany(SpaceExplorer::class);
}
}

La siguiente clase de ejemplo muestra cómo definir la relación inversa BelongsToMany de varios a varios entre los modelos SpaceExplorer y Planet usando el método belongsToMany():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\BelongsToMany;
class SpaceExplorer extends Model
{
protected $connection = 'mongodb';
public function planetsVisited(): BelongsToMany
{
return $this->belongsToMany(Planet::class);
}
}

El siguiente código de ejemplo muestra cómo instanciar un modelo para cada clase y agregar la relación entre ellas. Haz clic en el botón VIEW OUTPUT para ver los datos creados al ejecutar el código:

$planetEarth = new Planet();
$planetEarth->name = 'Earth';
$planetEarth->save();
$planetMars = new Planet();
$planetMars->name = 'Mars';
$planetMars->save();
$planetJupiter = new Planet();
$planetJupiter->name = 'Jupiter';
$planetJupiter->save();
$explorerTanya = new SpaceExplorer();
$explorerTanya->name = 'Tanya Kirbuk';
$explorerTanya->save();
$explorerMark = new SpaceExplorer();
$explorerMark->name = 'Mark Watney';
$explorerMark->save();
$explorerJeanluc = new SpaceExplorer();
$explorerJeanluc->name = 'Jean-Luc Picard';
$explorerJeanluc->save();
$explorerTanya->planetsVisited()->attach($planetEarth);
$explorerTanya->planetsVisited()->attach($planetJupiter);
$explorerMark->planetsVisited()->attach($planetEarth);
$explorerMark->planetsVisited()->attach($planetMars);
$explorerJeanluc->planetsVisited()->attach($planetEarth);
$explorerJeanluc->planetsVisited()->attach($planetMars);
$explorerJeanluc->planetsVisited()->attach($planetJupiter);
// Documents in the "planets" collection
[
{
_id: ObjectId('65e1043a5265269a03078ad0'),
name: 'Earth',
// ...
space_explorer_ids: [
'65e1043b5265269a03078ad3',
'65e1043b5265269a03078ad4',
'65e1043b5265269a03078ad5'
],
},
{
_id: ObjectId('65e1043a5265269a03078ad1'),
name: 'Mars',
// ...
space_explorer_ids: [ '65e1043b5265269a03078ad4', '65e1043b5265269a03078ad5' ]
},
{
_id: ObjectId('65e1043b5265269a03078ad2'),
name: 'Jupiter',
// ...
space_explorer_ids: [ '65e1043b5265269a03078ad3', '65e1043b5265269a03078ad5' ]
}
]
// Documents in the "space_explorers" collection
[
{
_id: ObjectId('65e1043b5265269a03078ad3'),
name: 'Tanya Kirbuk',
// ...
planet_ids: [ '65e1043a5265269a03078ad0', '65e1043b5265269a03078ad2' ]
},
{
_id: ObjectId('65e1043b5265269a03078ad4'),
name: 'Mark Watney',
// ...
planet_ids: [ '65e1043a5265269a03078ad0', '65e1043a5265269a03078ad1' ]
},
{
_id: ObjectId('65e1043b5265269a03078ad5'),
name: 'Jean-Luc Picard',
// ...
planet_ids: [
'65e1043a5265269a03078ad0',
'65e1043a5265269a03078ad1',
'65e1043b5265269a03078ad2'
]
}
]

El siguiente código de ejemplo muestra cómo acceder a los modelos relacionados utilizando las propiedades dinámicas tal como se define en las clases de ejemplo.

$planet = Planet::first();
$explorers = $planet->visitors;
$spaceExplorer = SpaceExplorer::first();
$explored = $spaceExplorer->planetsVisited;

En MongoDB, el patrón de documento incrustado añade los datos del modelo relacionado al modelo principal en lugar de conservar las referencias de claves foráneas. Utilice este patrón para cumplir uno o más de los siguientes requisitos:

  • Mantener los datos asociados juntos en una sola colección

  • Realizar actualizaciones atómicas en múltiples campos del documento y los datos asociados

  • Reducir la cantidad de lecturas requeridas para obtener los datos

En Laravel MongoDB, puedes definir documentos incrustados añadiendo uno de los siguientes métodos:

  • embedsOne() para incrustar un solo documento

  • embedsMany() para insertar múltiples documentos

Nota

Estos métodos devuelven colecciones de Eloquent, que difieren de los objetos del generador de consultas.

Cuando se utiliza un patrón de documento incrustado, la integración de Laravel recupera todos los datos incrustados del documento, a menos que se utilicen los métodos del generador de consultas select() o project(). Los datos integrados no se hidratan automáticamente en instancias de modelo. Para hidratar automáticamente los objetos incrustados, utiliza la propiedad $with al definir relaciones.

El siguiente ejemplo de código demuestra cómo utilizar la propiedad $with para hidratar automáticamente objetos incrustados:

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\EmbedsMany;
class User extends Model
{
protected $with = ['addresses'];
public function addresses()
{
return $this->embedsMany(Address::class);
}
}

Para obtener más información sobre el patrón de documentos incrustados de MongoDB, consulta los siguientes tutoriales de MongoDB Server:

La siguiente sección muestra un ejemplo de cómo utilizar el patrón de documento incrustado.

La siguiente clase de ejemplo muestra cómo definir un EmbedsMany de uno a muchos entre un modelo SpaceShip y Cargo utilizando el método embedsMany():

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
use MongoDB\Laravel\Relations\EmbedsMany;
class SpaceShip extends Model
{
protected $connection = 'mongodb';
public function cargo(): EmbedsMany
{
return $this->embedsMany(Cargo::class);
}
}

La clase de modelo incorporada omite la definición de relación como se muestra en la siguiente clase de modelo Cargo:

<?php
declare(strict_types=1);
namespace App\Models;
use MongoDB\Laravel\Eloquent\Model;
class Cargo extends Model
{
protected $connection = 'mongodb';
}

El siguiente código de ejemplo muestra cómo crear un modelo de SpaceShip e integrar varios modelos de Cargo, y también incluye el documento de MongoDB creado al ejecutar el código. Haz clic en el botón VIEW OUTPUT para ver los datos generados al ejecutar el código:

$spaceship = new SpaceShip();
$spaceship->name = 'The Millenium Falcon';
$spaceship->save();
$cargoSpice = new Cargo();
$cargoSpice->name = 'spice';
$cargoSpice->weight = 50;
$cargoHyperdrive = new Cargo();
$cargoHyperdrive->name = 'hyperdrive';
$cargoHyperdrive->weight = 25;
$spaceship->cargo()->attach($cargoSpice);
$spaceship->cargo()->attach($cargoHyperdrive);
// Document in the "space_ships" collection
{
_id: ObjectId('65e207b9aa167d29a3048853'),
name: 'The Millenium Falcon',
// ...
cargo: [
{
name: 'spice',
weight: 50,
// ...
_id: ObjectId('65e207b9aa167d29a3048854')
},
{
name: 'hyperdrive',
weight: 25,
// ...
_id: ObjectId('65e207b9aa167d29a3048855')
}
]
}

Una relación entre bases de datos cruzadas en Laravel MongoDB es una relación entre modelos almacenados en una base de datos relacional y modelos almacenados en una base de datos MongoDB.

Cuando añades una relación entre bases de datos, Eloquent te permite acceder a los modelos relacionados mediante una propiedad dinámica.

La integración de Laravel admite los siguientes métodos de relación entre bases de datos:

  • hasOne()

  • hasMany()

  • belongsTo()

Para definir una relación entre bases de datos, debe importar el paquete MongoDB\Laravel\Eloquent\HybridRelations en la clase almacenada en la base de datos relacional.

La siguiente sección muestra un ejemplo de cómo definir una relación entre bases de datos.

La siguiente clase de ejemplo muestra cómo definir una relación HasMany entre un modelo SpaceShip almacenado en una base de datos relacional y un modelo Passenger almacenado en una base de datos MongoDB:

<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use MongoDB\Laravel\Eloquent\HybridRelations;
class SpaceShip extends Model
{
use HybridRelations;
protected $connection = 'sqlite';
public function passengers(): HasMany
{
return $this->hasMany(Passenger::class);
}
}

La siguiente clase de ejemplo muestra cómo definir la relación inversa BelongsTo entre un modelo Passenger y el modelo Spaceship utilizando el método belongsTo():

<?php
declare(strict_types=1);
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use MongoDB\Laravel\Eloquent\Model;
class Passenger extends Model
{
protected $connection = 'mongodb';
public function spaceship(): BelongsTo
{
return $this->belongsTo(SpaceShip::class);
}
}

Tip

Asegúrese de que la llave primaria definida en el esquema de la tabla de su base de datos relacional coincida con la que utiliza su modelo. Para obtener más información sobre llaves primarias y definiciones de esquemas en Laravel, consulta las siguientes páginas en la documentación de Laravel:

El siguiente código de ejemplo muestra cómo crear un modelo SpaceShip en una base de datos MySQL y modelos Passenger relacionados en una base de datos MongoDB, así como los datos creados al ejecutar el código. Haz clic en el botón VIEW OUTPUT para ver los datos creados al ejecutar el código:

$spaceship = new SpaceShip();
$spaceship->id = 1234;
$spaceship->name = 'Nostromo';
$spaceship->save();
$passengerEllen = new Passenger();
$passengerEllen->name = 'Ellen Ripley';
$passengerDwayne = new Passenger();
$passengerDwayne->name = 'Dwayne Hicks';
$spaceship->passengers()->save($passengerEllen);
$spaceship->passengers()->save($passengerDwayne);
-- Row in the "space_ships" table
+------+----------+
| id | name |
+------+----------+
| 1234 | Nostromo |
+------+----------+
// Document in the "passengers" collection
[
{
_id: ObjectId('65e625e74903fd63af0a5524'),
name: 'Ellen Ripley',
space_ship_id: 1234,
// ...
},
{
_id: ObjectId('65e625e74903fd63af0a5525'),
name: 'Dwayne Hicks',
space_ship_id: 1234,
// ...
}
]

Volver

Clase de modelo Eloquent

En esta página