Relación Eloquent "One To One" en Laravel

Relación Eloquent "One To One" en Laravel

Esta relación nos permite obtener datos de una tabla que puede tener sólo una relación con otra tabla de manera sencilla y legible.

Imagina los siguientes escenarios:

  • Obtener el nombre del profesor de un curso:
1Course::first()->teacher->name;
  • Obtener oficina asignada de un profesor:
1Teacher::first()->office->location;

Como puedes ver, de una manera súper eloquent (elegante), podemos obtener los datos.

Laravel nos ofrece hasta 8 tipos de relaciones que podemos usar:

  • One To One
  • One To Many
  • Many To Many
  • Has One Through
  • Has Many Through
  • One To One (Polymorphic)
  • One To Many (Polymorphic)
  • Many To Many (Polymorphic)

En este post, empezaremos con la relación “One To One”.

One To One

Esta relación nos permite obtener datos de una tabla que puede tener solo una relación con otra tabla.

Ejemplos:

  • Una persona solo puede tener un pasaporte.
  • Un estudiante solo puede tener una tarjeta de identificación.
  • Un Pokémon solo puede tener una evolución Gigamax.

Para usar esta relación, solo tenemos que crear la relación en nuestro modelo principal.

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\HasOne;
7 
8class Pokemon extends Model
9{
10 public function gigamaxEvolution(): HasOne
11 {
12 return $this->hasOne(GigamaxEvolution::class);
13 }
14}

De esta manera, si queremos acceder a la mega evolución de un Pokémon, solo tenemos que escribir:

1// Charizard el Pokémon con ID: 6
2Pokemon::find(6)->gigamaxEvolution->description;
3 
4Resultado:
5"La energía del fenómeno Gigamax ha dotado a este Charizard de alas flamígeras y un enorme tamaño."

¡Súper sencillo! no?

Ahora, si queremos hacer el modo inverso, es decir, obtener el Pokémon que pertenece a una evolución Gigamax, entonces tenemos que agregar la relación inversa.

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7 
8class GigamaxEvolution extends Model
9{
10 public function pokemon(): BelongsTo
11 {
12 return $this->belongsTo(Pokemon::class);
13 }
14}
1// La evolución Gigamax de Charizard es la 10 (supongamos)
2GigamaxEvolution::find(10)->pokemon->name;
3 
4Resultado:
5"Charizard"

Observaciones Adicionales

Todo lo anterior es posible siempre y cuando sigamos el estándar de Laravel: las tablas en inglés y plural, los modelos en inglés y singular, y las llaves foráneas nombradas en singular con un guión bajo seguido de id.

Diagrama relacional entre pokemons y gigamax_evolutions

En caso de no seguir el estándar de Laravel, podemos usar los otros parámetros de la función hasOne. En este caso, foreign_key sería la llave en la tabla gigamax_evolutions que referencia a la tabla pokemons, y local_key sería el ID de la tabla pokemons.

1<?php
2 
3namespace App\Models;
4 
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\HasOne;
7 
8class Pokemon extends Model
9{
10 public function gigamaxEvolution(): HasOne
11 {
12 return $this->hasOne(GigamaxEvolution::class, 'foreign_key', 'local_key');
13 }
14}

Si quieres conocer más acerca de las otras relaciones Eloquent, ¡no olvides suscribirte al newsletter aquí abajo y al canal de Youtube!

Regístrate para que cada semana aprendas algo nuevo

Tendrás tutoriales, tips, conceptos y puedas convertirte en un artesano de todo el ecosistema Laravel.

Nuevo Curso
Chat en Tiempo Real con Laravel Broadcasting

Revisa los detalles del nuevo curso en desarrollo

App screenshot