Relacionamentos de modelo eloquente
Nesta página
- Visão geral
- Relacionamento individual
- Exemplo individual
- Relacionamento de um para muitos
- Exemplo de um para muitos
- Relacionamento de muitos para muitos
- Exemplo de muitos para muitos
- Padrão de documento incorporado
- Exemplo de documento incorporado
- Relacionamentos entre bancos de dados
- Exemplo de relacionamento entre bancos de dados
Visão geral
Quando você usa um banco de banco de dados relacional, o Eloquent ORM armazena modelos como linhas em tabelas que correspondem às classes de modelo. Quando você usa MongoDB, a integração do Laravel armazena modelos como documentos em coleções que correspondem às classes de modelo.
Para definir um relacionamento, adicione uma função à classe de modelo que chama o método de relacionamento apropriado. Esta função permite a você acessar o modelo relacionado como uma propriedade dinâmica. Uma propriedade dinâmica permite acessar o modelo relacionado usando a mesma sintaxe usada para acessar uma propriedade no modelo.
As seções a seguir descrevem as relações específicas do Laravel Eloquent e do MongoDB disponíveis na integração do Laravel e mostram exemplos de como defini-las e usá-las:
Relacionamento um para um, criado usando o método
hasOne()
e seu inverso,belongsTo()
Relacionamento de um para muitos, criado usando
hasMany()
e seu inverso,belongsTo()
Relacionamento Muitos para muitos, criado usando o método
belongsToMany()
Padrão de documento incorporado, um relacionamento específico do MongoDB que pode representar um relacionamento de um para um ou de um para muitos, criado usando o método
embedsOne()
ouembedsMany()
Relacionamentos entre bancos de dados, necessários quando você deseja criar relacionamentos entre os modelos MongoDB e SQL
Relacionamento individual
Um relacionamento um para um entre modelos consiste em um registro de modelo relacionado a exatamente um outro tipo de registro de modelo.
Quando você adiciona um relacionamento um a um, o Eloquent permite acessar o modelo usando uma propriedade dinâmica e armazena o ID do documento do modelo no modelo relacionado.
No Laravel MongoDB, você pode definir um relacionamento um para um usando o método hasOne()
ou belongsTo()
.
Quando você adiciona o inverso do relacionamento usando o método belongsTo()
, o Eloquent permite acessar o modelo usando uma propriedade dinâmica, mas não adiciona nenhum campo.
Para saber mais sobre relacionamentos um para um, consulte Um para Um na documentação do Laravel.
Exemplo individual
A seguinte classe de exemplo mostra como definir um relacionamento um para um HasOne
entre um modelo Planet
e Orbit
utilizando o método hasOne()
:
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); } }
A seguinte classe de exemplo mostra como definir a relação BelongsTo
inversa entre Orbit
e Planet
utilizando o método belongsTo()
:
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); } }
O código de amostra a seguir mostra como instanciar um modelo para cada classe e adicionar o relacionamento entre eles. Clique no botão VIEW OUTPUT para ver os dados criados executando o 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', // ... }
O seguinte código de amostra mostra como acessar os modelos relacionados usando as propriedades dinâmicas conforme definido nas classes de exemplo:
$planet = Planet::first(); $relatedOrbit = $planet->orbit; $orbit = Orbit::first(); $relatedPlanet = $orbit->planet;
Relacionamento de um para muitos
Um relacionamento um para muitos entre modelos consiste em um modelo que é o pai e um ou mais registros de modelo filho relacionados.
Quando você adiciona um método de relacionamento de um para muitos, o Eloquent permite acessar o modelo usando uma propriedade dinâmica e armazena o ID do documento do modelo principal em cada documento do modelo filho.
No Laravel MongoDB, você pode definir um relacionamento de um para muitos adicionando o método hasMany()
na classe pai e, opcionalmente, o método belongsTo()
na classe filho.
Quando você adiciona o inverso do relacionamento usando o método belongsTo()
, o Eloquent permite acessar o modelo principal usando uma propriedade dinâmica sem adicionar nenhum campo.
Para saber mais sobre relacionamentos um a muitos, consulte Um a muitos na documentação do Laravel.
Exemplo de um para muitos
A seguinte classe de exemplo mostra como definir um relacionamento HasMany
um para muitos entre um modelo pai Planet
e um modelo filho Moon
usando o método hasMany()
:
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); } }
A classe de exemplo a seguir mostra como definir o relacionamento BelongsTo
inverso entre um modelo filho Moon
e o modelo pai Planet
usando o método belongsTo()
:
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); } }
O código de amostra a seguir mostra como instanciar um modelo para cada classe e adicionar o relacionamento entre eles. Clique no botão VIEW OUTPUT para ver os dados criados ao executar o 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', // ... } ]
O código de amostra a seguir mostra como acessar os modelos relacionados usando as propriedades dinâmicas conforme definido nas classes de exemplo.
$planet = Planet::first(); $relatedMoons = $planet->moons; $moon = Moon::first(); $relatedPlanet = $moon->planet;
Relacionamento de muitos para muitos
Um relacionamento muitos para muitos consiste em um relacionamento entre dois tipos de modelo diferentes no qual, para cada tipo de modelo, uma instância do modelo pode estar relacionada a múltiplas instâncias do outro tipo.
No Laravel MongoDB, você pode definir um relacionamento de muitos para muitos adicionando o método belongsToMany()
a ambas as classes relacionadas.
Quando você define um relacionamento muitos para muitos em um banco de banco de dados relacional, o Laravel cria uma tabela dinâmica para rastrear os relacionamentos. Quando você usa a Integração Laravel, ela omite a criação da tabela dinâmica e adiciona os IDs de documento relacionados a um campo de documento derivado do nome da classe de modelo relacionado.
Dica
Como a integração do Laravel usa um campo de documento em vez de uma tabela dinâmica, omita o parâmetro da tabela dinâmica do construtor belongsToMany()
ou defina-o como null
.
Para saber mais sobre relacionamentos muitos para muitos no Laravel, consulte Muitos para muitos na documentação do Laravel.
A seção a seguir mostra um exemplo de como criar um relacionamento de muitos para muitos entre as classes de modelo.
Exemplo de muitos para muitos
A classe de exemplo a seguir mostra como definir um relacionamento BelongsToMany
de muitos para muitos entre um modelo Planet
e SpaceExplorer
usando o método belongsToMany()
:
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); } }
A classe de exemplo a seguir mostra como definir o relacionamento BelongsToMany
muitos para muitos inverso entre um modelo SpaceExplorer
e Planet
usando o método belongsToMany()
:
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); } }
O código de amostra a seguir mostra como instanciar um modelo para cada classe e adicionar o relacionamento entre eles. Clique no botão VIEW OUTPUT para ver os dados criados ao executar o 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' ] } ]
O código de amostra a seguir mostra como acessar os modelos relacionados usando as propriedades dinâmicas conforme definido nas classes de exemplo.
$planet = Planet::first(); $explorers = $planet->visitors; $spaceExplorer = SpaceExplorer::first(); $explored = $spaceExplorer->planetsVisited;
Padrão de documento incorporado
No MongoDB, o padrão de documento incorporado adiciona os dados do modelo relacionado ao modelo principal em vez de manter as referências de chave estrangeira. Use esse padrão para atender a um ou mais dos seguintes requisitos:
Mantendo dados associados juntos em uma única collection
Executando atualizações atômicas em vários campos do documento e os dados associados
Reduzindo o número de leituras necessárias para buscar os dados
No Laravel MongoDB, você pode definir documentos incorporados adicionando um dos seguintes métodos:
embedsOne()
para incorporar um único documentoembedsMany()
para incorporar vários documentos
Observação
Esses métodos retornam coleções Eloquent, que diferem dos objetos do construtor de query.
Para saber mais sobre o padrão de documento incorporado do MongoDB , consulte os seguintes tutoriais do MongoDB Server :
Modelar relacionamentos de um para um com documentos incorporados
Modele relacionamentos um-para-muitos com documentos incorporados
A seção a seguir mostra um exemplo de como usar o padrão de documento incorporado.
Exemplo de documento incorporado
A seguinte classe de exemplo mostra como definir um relacionamento EmbedsMany
um para muitos entre um modelo SpaceShip
e Cargo
utilizando o método embedsMany()
:
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); } }
A classe de modelo incorporada omite a definição de relacionamento, conforme mostrado na seguinte classe de modelo Cargo
:
declare(strict_types=1); namespace App\Models; use MongoDB\Laravel\Eloquent\Model; class Cargo extends Model { protected $connection = 'mongodb'; }
O código de exemplo a seguir mostra como criar um modelo SpaceShip
e incorporar vários modelos Cargo
e o documento MongoDB criado executando o código. Clique no botão VIEW OUTPUT para ver os dados criados ao executar o 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') } ] }
Relacionamentos entre bancos de dados
Um relacionamento entre bancos de dados no Laravel MongoDB é um relacionamento entre modelos armazenados em um banco de dados relacional e modelos armazenados em um banco de MongoDB database.
Quando você adiciona um relacionamento entre bancos de dados, o Eloquent permite acessar os modelos relacionados usando uma propriedade dinâmica.
A integração do Laravel suporta os seguintes métodos de relacionamento entre bancos de dados:
hasOne()
hasMany()
belongsTo()
Para definir um relacionamento entre bancos de dados, você deve importar o pacote MongoDB\Laravel\Eloquent\HybridRelations
na classe armazenada no banco de dados relacional.
A seção a seguir mostra um exemplo de como definir um relacionamento entre bancos de dados.
Exemplo de relacionamento entre bancos de dados
A seguinte classe de exemplo mostra como definir um relacionamento HasMany
entre um modelo SpaceShip
armazenado em um banco de dados relacional e um modelo Passenger
armazenado em um banco de MongoDB database:
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); } }
A classe de exemplo a seguir mostra como definir a relação BelongsTo
inversa entre um modelo Passenger
e o modelo Spaceship
usando o método belongsTo()
:
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); } }
Dica
Certifique-se de que a chave primária definida no esquema de tabela do banco de dados relacional corresponda à chave usada pelo seu modelo. Para saber mais sobre as chaves primárias e definições de esquema do Laravel, consulte as seguintes páginas na documentação do Laravel:
O código de exemplo a seguir mostra como criar um modelo SpaceShip
em um banco de dados MySQL e modelos Passenger
relacionados em um banco de MongoDB database , bem como os dados criados pela execução do código. Clique no botão VIEW OUTPUT para ver os dados criados ao executar o 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, // ... } ]