09-10-2026
Relaciones con laravel eloquent: la guía definitiva que todo desarrollador debe dominar
Eloquent permite tratar las tablas de la base de datos como si fueran objetos de PHP. Cuando se dominan las relaciones, se deja de escribir consultas larguísimas y se gana en claridad. El código queda más limpio y se entiende mejor qué tiene que ver cada cosa con cada cosa.
hasOne_ Relación Uno a uno
Caso típico: un usuario tiene un único perfil.
// En el modelo User
public function profile()
{
return $this->hasOne(Profile::class);
}
// En el modelo Profile
public function user()
{
return $this->belongsTo(User::class);
}
Tablas típicas:
- users: id, name, email
- profiles: id, user_id, bio, address
belongsTo — La otra cara del uno a uno
Es simplemente decir que el perfil pertenece a un usuario. Es el inverso del anterior.
hasMany — Uno a muchos
La más usada con diferencia. Un usuario tiene muchos posts.
// User
public function posts()
{
return $this->hasMany(Post::class);
}
// Post
public function user()
{
return $this->belongsTo(User::class);
}
belongsToMany — Muchos a muchos
Aquí hace falta una tabla intermedia, conocida como "tabla pivot". El ejemplo clásico son los usuarios y los roles.
// User
public function roles()
{
return $this->belongsToMany(Role::class);
}
// Role
public function users()
{
return $this->belongsToMany(User::class);
}
La tabla del medio suele llamarse "role_user" y guarda los dos identificadores.
hasOneThrough — Uno a uno pasando por en medio
Un país tiene un perfil, pero no directamente, sino a través de los usuarios.
public function profile()
{
return $this->hasOneThrough(
Profile::class,
User::class,
'country_id',
'user_id',
'id',
'id'
);
}
hasManyThrough — Uno a muchos pasando por en medio
Un país tiene muchos posts, otra vez pasando por los usuarios.
public function posts()
{
return $this->hasManyThrough(
Post::class,
User::class,
'country_id',
'user_id',
'id',
'id'
);
}
Relaciones polimórficas
Aquí un comentario puede pertenecer tanto a un post como a un vídeo.
// En Post o en Video
public function comments()
{
return $this->morphMany(Comment::class, 'commentable');
}
// En Comment
public function commentable()
{
return $this->morphTo();
}
En la tabla de comentarios se guardan dos campos: el identificador y a que pertenece, un post, vídeo,etc.. al que pertenece.
Consultas más usadas
// Cargar un usuario con su perfil
$user = User::with('profile')->find(1);
// Usuario con todos sus posts
$user = User::with('posts')->find(1);
// Posts con el usuario de cada uno
$posts = Post::with('user')->get();
// Cargar varias relaciones de golpe
$user = User::with(['profile', 'posts', 'roles'])->find(1);
Consejos prácticos
- Ponerle a los métodos nombres que se entiendan a la primera.
- Definir bien las claves en las migraciones desde el principio.
- Usar "with()" siempre que se pueda para no hacer mil consultas innecesarias.
- Seguir las convenciones de Laravel; el código se lee mucho mejor.
- En las relaciones de muchos a muchos, la tabla intermedia es casi obligatoria.
- Cuando el asunto se complica, echar un vistazo a la documentación oficial.