- Introducción
- Definiendo relaciones
- Relaciones polimórficas
- Consultando relaciones
- Precarga (eager loading)
- Insertando y actualizando modelos relacionados
- Tocando marcas de tiempo del padre
Introducción
Las tablas de base de datos frecuentemente están relacionadas a otra tabla. Por ejemplo, un post de un blog puede tener muchos comentarios o un pedido podría estar relacionado al usuario que lo ordenó. Eloquent hace que manejar y trabajar con estas relaciones sea fácil y soporta varios tipos de relaciones:
- Uno a Uno
- Uno a Muchos
- Muchos a Muchos
- Uno a Través de
- Muchos a Través de
- Uno a Uno (Polimórfica)
- Uno a Muchos (Polimórfica)
- Muchos a Muchos (Polimórfica)
Definiendo relaciones
Las relaciones de Eloquent se definen como métodos en tus clases de modelo de Eloquent. Debido a que, como los mismos modelos Eloquent, las relaciones también sirven como poderosos constructores de consultas, el definir relaciones como métodos proporciona potentes capacidades de encadenamiento de métodos y consultas. Por ejemplo, podemos encadenar restricciones adicionales en esta relación posts
:
$user->posts()->where('active', 1)->get();
Pero, antes de profundizar demasiado en el uso de relaciones, aprendamos cómo definir cada tipo.
Los nombres de las relaciones no pueden colisionar con nombres de atributos dado que eso podría ocasionar que tu modelo no sea capaz de saber cuál resolver.
Uno A Uno
Una relación de uno a uno es una relación muy sencilla. Por ejemplo, un modelo User
podría estar asociado con un Phone
. Para definir esta relación, colocaremos un método phone
en el modelo User
. El método phone
debería llamar al método hasOne
y devolver su resultado:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * Get the phone record associated with the user. */ public function phone() { return $this->hasOne('App\Phone'); } }
El primer argumento pasado al método hasOne
es el nombre del modelo relacionado. Una vez que la relación es definida, podemos obtener el registro relacionado usando propiedades dinámicas de Eloquent. Las propiedades dinámicas permiten que accedas a métodos de relación como si fueran propiedades definidas en el modelo:
$phone = User::find(1)->phone;
Eloquent determina la clave foránea de la relación en base al nombre del modelo. En este caso, se asume automáticamente que el modelo Phone
tenga una clave foránea user_id
. Si deseas sobrescribir esta convención, puedes pasar un segundo argumento al método hasOne
:
return $this->hasOne('App\Phone', 'foreign_key');
Adicionalmente, Eloquent asume que la clave foránea debería tener un valor que coincida con la columna id
(o $primaryKey
personalizada) del padre. En otras palabras, Eloquent buscará el valor de la columna id
del usuario en la columna user_id
de Phone
. Si prefieres que la relación use un valor distinto de id
, puedes pasar un tercer argumento al método hasOne
especificando tu clave personalizada:
return $this->hasOne('App\Phone', 'foreign_key', 'local_key');
Definiendo el inverso de la relación
Así, podemos acceder al modelo Phone
desde nuestro User
. Ahora, vamos a definir una relación en el modelo Phone
que nos permitirá acceder al User
que posee el teléfono. Podemos definir el inverso de una relación hasOne
usando el método belongsTo
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Phone extends Model { /** * Get the user that owns the phone. */ public function user() { return $this->belongsTo('App\User'); } }
En el ejemplo anterior, Eloquent intentará hacer coincidir el user_id
del modelo Phone
con un id
en el modelo User
. Eloquent determina el nombre de la clave foránea de forma predeterminada al examinar el nombre del método de la relación y agregando el sufijo al nombre del método con _id
. Sin embargo, si la clave foránea en el modelo Phone
no es user_id
, puedes pasar un nombre de clave personalizada como segundo argumento al método belongsTo
:
/** * Get the user that owns the phone. */ public function user() { return $this->belongsTo('App\User', 'foreign_key'); }
Si tu modelo padre no usa id
como su clave primaria, o deseas hacer join al modelo hijo con una columna diferente, puedes pasar un tercer argumento al método belongsTo
especificando la clave personalizada de tu tabla padre:
/** * Get the user that owns the phone. */ public function user() { return $this->belongsTo('App\User', 'foreign_key', 'other_key'); }
Uno a muchos
Una relación de «uno-a-muchos» es usada para definir relaciones donde un solo modelo posee cualquier cantidad de otros modelos. Por ejemplo, un post de un blog puede tener un número infinito de comentarios. Al igual que todas las demás relaciones de Eloquent, las relaciones uno-a-muchos son definidas al colocar una función en tu modelo Eloquent:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * Get the comments for the blog post. */ public function comments() { return $this->hasMany('App\Comment'); } }
Recuerda, Eloquent determinará automáticamente la columna de clave foránea apropiada en el modelo Comment
. Por convención, Eloquent tomará el nombre «snake case» del modelo que la contiene y le agregará el sufijo _id
. Para este ejemplo, Eloquent asumirá que la clave foránea del modelo Comment
es post_id
.
Una vez que la relación ha sido definida, podemos acceder a la colección de comentarios al acceder a la propiedad comments
. Recuerda, ya que Eloquent proporciona «propiedades dinámicas», podemos acceder a los métodos de la relación como si fueran definidos como propiedades en el modelo:
$comments = App\Post::find(1)->comments; foreach ($comments as $comment) { // }
Debido a que todas las relaciones también sirven como constructores de consultas (query builders), puedes agregar restricciones adicionales a cuyos comentarios sean obtenidos ejecutando el método comments
y encadenando condiciones en la consulta:
$comment = App\Post::find(1)->comments()->where('title', 'foo')->first();
Igual que el método hasOne
, también puedes sobrescribir las claves foráneas y locales al pasar argumentos adicionales al método hasMany
:
return $this->hasMany('App\Comment', 'foreign_key'); return $this->hasMany('App\Comment', 'foreign_key', 'local_key');
Uno a muchos (inverso)
Ahora que puedes acceder a todos los comentarios de un post, vamos a definir una relación para permitir a un comentario acceder a su post padre. Para definir el inverso de una relación hasMany
, define una función de relación en el modelo hijo que ejecute el método belongsTo
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * Get the post that owns the comment. */ public function post() { return $this->belongsTo('App\Post'); } }
Una vez que la relación ha sido definida, podemos obtener el modelo Post
para un Comment
accediendo a la «propiedad dinámica» de post
:
$comment = App\Comment::find(1); echo $comment->post->title;
En el ejemplo anterior, Eloquent tratará de hacer coincidir el post_id
del modelo Comment
con un id
en el modelo Post
. Eloquent determina el nombre de la clave foránea por defecto, examinando el nombre del método de la relación y agregando un sufijo _
al nombre del método, seguido del nombre de la columna principal de la llave. Sin embargo, si la clave foránea en el modelo Comment
no es post_id
, puedes pasar un nombre de clave personalizado como segundo argumento al método belongsTo
:
/** * Get the post that owns the comment. */ public function post() { return $this->belongsTo('App\Post', 'foreign_key'); }
Si tu modelo padre no usa id
como su clave primaria, o deseas hacer join al modelo hijo con una columna diferente, puedes pasar un tercer argumento al método belongsTo
especificando la clave personalizada de tu tabla padre.
/** * Get the post that owns the comment. */ public function post() { return $this->belongsTo('App\Post', 'foreign_key', 'other_key'); }
Muchos a muchos
Las relaciones de muchos-a-muchos son ligeramente más complicadas que las relaciones hasOne
y hasMany
. Un ejemplo de tal relación es un usuario con muchos roles, donde los roles también son compartidos por otros usuarios. Por ejemplo, muchos usuarios pueden tener el rol «Admin».
Estructura de la tabla
Para definir esta relación, tres tablas de bases de datos son necesitadas: users
, roles
, y role_user
. La tabla role_user
es derivada del orden alfabético de los nombres de modelo relacionados y contiene las columnas user_id
y role_id
.
users id - integer name - string roles id - integer name - string role_user user_id - integer role_id - integer
Estructura del modelo
Las relaciones de muchos-a-muchos son definidas escribiendo un método que devuelve el resultado del método belongsToMany
. Por ejemplo, vamos a definir el método roles
en nuestro modelo User
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * The roles that belong to the user. */ public function roles() { return $this->belongsToMany('App\Role'); } }
Una vez que la relación es definida, puedes acceder a los roles del usuario usando la propiedad dinámica roles
:
$user = App\User::find(1); foreach ($user->roles as $role) { // }
Como con los otros tipos de relación, puedes ejecutar el método roles
para continuar encadenando las restricciones de consulta en la relación:
$roles = App\User::find(1)->roles()->orderBy('name')->get();
Como mencionamos previamente, para determinar el nombre de la tabla asociativa, Eloquent juntará los dos nombres de modelo en orden alfabético. Sin embargo, eres libre de sobrescribir esta convención. Puedes hacer eso pasando un segundo argumento al método belongsToMany
:
return $this->belongsToMany('App\Role', 'role_user');
Además de personalizar el nombre de la tabla asociativa, también puedes personalizar los nombres de columna de las claves en la tabla pasando argumentos adicionales al método belongsToMany
. El tercer argumento es el nombre de clave foránea del modelo en el cual estás definiendo la relación, mientras el cuarto argumento es el nombre de la clave foránea del modelo que estás asociando:
return $this->belongsToMany('App\Role', 'role_user', 'user_id', 'role_id');
Definiendo el inverso de la relación
Para definir el inverso de una relación de muchos-a-muchos, puedes colocar otra llamada de belongsToMany
en tu modelo relacionado. Para continuar con nuestro ejemplo de roles de usuario, vamos a definir el método users
en el modelo Role
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model { /** * The users that belong to the role. */ public function users() { return $this->belongsToMany('App\User'); } }
Como puedes ver, la relación es definida exactamente de la misma forma que su contraparte User
, con la excepción de que referencia al modelo App\User
. Ya que estamos reusando el método belongsToMany
, todas las tablas y opciones de personalización de claves usuales están disponibles al momento de definir el inverso de las relaciones de muchos-a-muchos.
Obteniendo columnas de tablas intermedias (Pivote)
Como ya has aprendido, trabajar con relaciones de muchos-a-muchos requiere la presencia de una tabla intermedia o pivote. Eloquent proporciona algunas formas muy útiles de interactuar con esta tabla. Por ejemplo, vamos a asumir que nuestro objeto User
tiene muchos objetos Role
al que está relacionado. Después de acceder a esta relación, podemos acceder a la tabla intermedia usando el atributo pivot
en los modelos:
$user = App\User::find(1); foreach ($user->roles as $role) { echo $role->pivot->created_at; }
Ten en cuenta que a cada modelo Role
que obtenemos se le asigna automáticamente un atributo pivot
. Este atributo contiene un modelo que representa la tabla intermedia y puede ser usado como cualquier otro modelo de Eloquent.
De forma predeterminada, solo las claves del modelo estarán presentes en el objeto pivot
. Si tu tabla pivote contiene atributos extras, debes especificarlos cuando definas la relación.
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
Si quieres que tu tabla pivote automáticamente mantenga las marcas de tiempo created_at
y updated_at
, usa el método withTimestamps
en la definición de la relación:
return $this->belongsToMany('App\Role')->withTimestamps();
Personalizando el nombre del atributo pivot
Como se señaló anteriormente, los atributos de la tabla intermedia pueden ser accedidos en modelos usando el atributo pivot
. Sin embargo, eres libre de personalizar el nombre de este atributo para que refleje mejor su propósito dentro de tu aplicación.
Por ejemplo, si tu aplicación contiene usuarios que pueden suscribirse a podcasts, probablemente tengas una relación de muchos-a-muchos entre usuarios y podcasts. Si éste es el caso, puedes desear renombrar tu tabla pivote intermedia como subscription
en lugar de pivot
. Esto se puede hacer usando el método as
al momento de definir la relación:
return $this->belongsToMany('App\Podcast') ->as('subscription') ->withTimestamps();
Una vez hecho esto, puedes acceder a los datos de la tabla intermedia usando el nombre personalizado:
$users = User::with('podcasts')->get(); foreach ($users->flatMap->podcasts as $podcast) { echo $podcast->subscription->created_at; }
Filtrando relaciones a través de columnas de tablas intermedias
También puedes filtrar los resultados devueltos por belongsToMany
usando los métodos wherePivot
, wherePivotIn
y wherePivotNotIn
al momento de definir la relación:
return $this->belongsToMany('App\Role')->wherePivot('approved', 1); return $this->belongsToMany('App\Role')->wherePivotIn('priority', [1, 2]); return $this->belongsToMany('App\Role')->wherePivotNotIn('priority', [1, 2]);
Definiendo modelos de tabla intermedia personalizados
Si prefieres definir un modelo personalizado para representar la tabla intermedia o pivote de tu relación, puedes ejecutar el método using
al momento de definir la relación. Los modelos de tablas intermedias de muchos-a-muchos personalizados deben extender la clase Illuminate\Database\Eloquent\Relations\Pivot
mientras que los modelos polimórficos muchos-a-muchos deben extender la clase Illuminate\Database\Eloquent\Relations\MorphPivot
. Por ejemplo, podemos definir un Role
que use un modelo pivote RoleUser
personalizado:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model { /** * The users that belong to the role. */ public function users() { return $this->belongsToMany('App\User')->using('App\RoleUser'); } }
Al momento de definir el modelo RoleUser
, extenderemos la clase Pivot
:
<?php namespace App; use Illuminate\Database\Eloquent\Relations\Pivot; class RoleUser extends Pivot { // }
Puedes combinar using
y withPivot
para retornar columnas de la tabla intermedia. Por ejemplo, puedes retornar las columnas created_by
y updated_by
desde la tabla pivote RoleUser
pasando los nombres de las columnas al método withPivot
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Role extends Model { /** * The users that belong to the role. */ public function users() { return $this->belongsToMany('App\User') ->using('App\RoleUser') ->withPivot([ 'created_by', 'updated_by', ]); } }
Nota: Los modelos Pivot no pueden usar el trait SoftDeletes
. Si necesitas hacer eliminación lógica (soft delete) de registros pivot considera convertir tu modelo pivot a un modelo de Eloquent.
Modelos de pivote personalizados e IDs incrementales
Si has definido una relación de muchos a muchos que usa un modelo de pivote personalizado, y ese modelo de pivote tiene una clave primaria de incremento automático, debes asegurarte de que su clase de modelo de pivote personalizado defina una propiedad incrementing
que se establece en true
.
/** * Indicates if the IDs are auto-incrementing. * * @var bool */ public $incrementing = true;
Tiene uno a través de (hasOneThrough)
La relación «tiene-uno-a-través-de» vincula los modelos a través de una única relación intermedia.
Por ejemplo, si cada proveedor (supplier) tiene un usuario (user) y cada usuario está asociado con un registro del historial (history) de usuarios, entonces el modelo del proveedor puede acceder al historial del usuario a través del usuario. Veamos las tablas de base de datos necesarias para definir esta relación:
users id - integer supplier_id - integer suppliers id - integer history id - integer user_id - integer
Aunque la tabla history
no contiene una columna supplier_id
, la relación hasOneThrough
puede proporcionar acceso al historial del usuario desde el modelo del proveedor. Ahora que hemos examinado la estructura de la tabla para la relación, vamos a definirla en el modelo Supplier
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Supplier extends Model { /** * Get the user's history. */ public function userHistory() { return $this->hasOneThrough('App\History', 'App\User'); } }
El primer argumento pasado al método hasOneThrough
es el nombre del modelo final al que queremos acceder, mientras que el segundo argumento es el nombre del modelo intermedio.
Se utilizarán las convenciones típicas de clave foránea de Eloquent al realizar las consultas de la relación. Si deseas personalizar las claves de la relación, puedes pasarlas como el tercer y cuarto argumento al método hasOneThrough
. El tercer argumento es el nombre de la clave foránea en el modelo intermedio. El cuarto argumento es el nombre de la clave foránea en el modelo final. El quinto argumento es la clave local, mientras que el sexto argumento es la clave local del modelo intermedio:
class Supplier extends Model { /** * Get the user's history. */ public function userHistory() { return $this->hasOneThrough( 'App\History', 'App\User', 'supplier_id', // Foreign key on users table... 'user_id', // Foreign key on history table... 'id', // Local key on suppliers table... 'id' // Local key on users table... ); } }
Tiene muchos a través de (hasManyThrough)
La relación «tiene-muchos-a-través-de» proporciona una abreviación conveniente para acceder a relaciones distantes por medio de una relación intermedia. Por ejemplo, un modelo Country
podría tener muchos modelos Post
a través de un modelo User
intermedio. En este ejemplo, podrías traer todos los posts de un blog para un país dado. Vamos a buscar las tablas requeridas para definir esta relación:
countries id - integer name - string users id - integer country_id - integer name - string posts id - integer user_id - integer title - string
Aunque los posts
no contienen una columna country_id
, la relación hasManyThrough
proporciona acceso a los posts de un país por medio de $country->posts
. Para ejecutar esta consulta, Eloquent inspecciona el country_id
de la tabla intermedia users
. Después de encontrar los ID de usuario que coincidan, serán usados para consultar la tabla posts
.
Ahora que hemos examinado la estructura de la tabla para la relación, vamos a definirla en el modelo Country
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Country extends Model { /** * Get all of the posts for the country. */ public function posts() { return $this->hasManyThrough('App\Post', 'App\User'); } }
El primer argumento pasado al método hasManyThrough
es el nombre del modelo final que deseamos acceder, mientras que el segundo argumento es el nombre del modelo intermedio.
Las convenciones de clave foránea típicas de Eloquent serán usadas al momento de ejecutar las consultas de la relación. Si prefieres personalizar las claves de la relación, puedes pasarlos como tercer y cuarto argumentos del método hasManyThrough
. El tercer argumento es el nombre de la clave foránea en el modelo intermedio. El cuarto argumento es el nombre de la clave foránea en el modelo final. El quinto argumento es la clave local, mientras el sexto argumento es la clave local del modelo intermedio:
class Country extends Model { public function posts() { return $this->hasManyThrough( 'App\Post', 'App\User', 'country_id', // Foreign key on users table... 'user_id', // Foreign key on posts table... 'id', // Local key on countries table... 'id' // Local key on users table... ); } }
Relaciones polimórficas
Una relación polimórfica permite que el modelo objetivo pertenezca a más de un tipo de modelo usando una sola asociación.
Una a una (polimórfica)
Estructura de tabla
Una relación polimórfica de uno-a-uno es similar a una relación de uno-a-uno simple; sin embargo, el modelo objetivo puede pertenecer a más de un tipo de modelo en una sola asociación. Por ejemplo, un Post
de un blog y un User
pueden compartir una relación polimórfica con un modelo Image
. El uso de una relación polimórfica de uno-a-uno te permite tener una sola lista de imágenes únicas que son usadas tanto por los posts del blog como por las cuentas de los usuarios. Primero, vamos a examinar la estructura de la tabla:
posts id - integer name - string users id - integer name - string images id - integer url - string imageable_id - integer imageable_type - string
Observa las columnas imageable_id
y imageable_type
en la tabla images
. La columna imageable_id
contendrá el valor del ID del post o del usuario, mientras que la columna imageable_type
contendrá el nombre de clase del modelo padre. La columna imageable_type
es usada por Eloquent para determinar cuál «tipo» de modelo padre retornar al acceder a la relación imageable
.
Estructura del modelo
A continuación, vamos a examinar las definiciones de modelo necesarias para construir esta relación:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Image extends Model { /** * Get the owning imageable model. */ public function imageable() { return $this->morphTo(); } } class Post extends Model { /** * Get the post's image. */ public function image() { return $this->morphOne('App\Image', 'imageable'); } } class User extends Model { /** * Get the user's image. */ public function image() { return $this->morphOne('App\Image', 'imageable'); } }
Retornando la relación
Una vez que tu tabla en la base de datos y modelos son definidos, puedes acceder a las relaciones mediante tus modelos. Por ejemplo, para retornar la imagen para un post, podemos usar la propiedad dinámica image
:
$post = App\Post::find(1); $image = $post->image;
Puedes también retornar el padre del modelo polimórfico accediendo al nombre del método que realiza la llamada a morphTo
. En nuestro caso, éste es el método imageable
en el modelo Image
. Entonces, accederemos al método como una propiedad dinámica:
$image = App\Image::find(1); $imageable = $image->imageable;
La relación imageable
en el modelo Image
retornará ya sea una instancia de Post
o User
, dependiendo del tipo de modelo que posea la imagen.
Uno a muchos (Polimórfica)
Estructura de tabla
Una relación polimórfica de uno-a-muchos es similar a una relación de uno-a-muchos sencilla; sin embargo, el modelo objetivo puede pertenecer a más de un tipo de modelo en una sola asociación. Por ejemplo, imagina que usuarios de tu aplicación pueden «comentar» tanto en posts como en videos. Usando relaciones polimórficas, puedes usar una sola tabla comments
para ambos escenarios. Primero, vamos a examinar la estructura de tabla requerida para esta relación:
posts id - integer title - string body - text videos id - integer title - string url - string comments id - integer body - text commentable_id - integer commentable_type - string
Estructura de modelo
A continuación, vamos a examinar las definiciones de modelos necesarias para construir esta relación:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * Get the owning commentable model. */ public function commentable() { return $this->morphTo(); } } class Post extends Model { /** * Get all of the post's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } } class Video extends Model { /** * Get all of the video's comments. */ public function comments() { return $this->morphMany('App\Comment', 'commentable'); } }
Retornando la relación
Una vez que tu tabla en la base de datos y modelos son definidos, puedes acceder a las relaciones mediante tus modelos. Por ejemplo, para acceder a todos los comentarios de un post, podemos usar la propiedad dinámica comments
:
$post = App\Post::find(1); foreach ($post->comments as $comment) { // }
También puedes retornar al propietario de una relación polimórfica desde un modelo polimórfico accediendo al nombre del método que realiza la llamada a morphTo
. En nuestro caso, éste es el método commentable
en el modelo Comment
. Así que, accederemos a dicho método como una propiedad dinámica:
$comment = App\Comment::find(1); $commentable = $comment->commentable;
La relación commentable
en el modelo Comment
retornará ya sea una instancia Post
o Video
, dependiendo de qué tipo de modelo es el propietario del comentario.
Muchos A Muchos (Polimórfica)
Estructura de tabla
Las relaciones polimórficas de muchos-a-muchos son un poco más complicadas que las relaciones morphOne
y morphMany
. Por ejemplo, un modelo Post
de un blog y un modelo Video
pueden compartir una relación polimórfica con un modelo Tag
. El uso de una relación polimórfica de muchos-a-muchos te permite tener una única lista de etiquetas que son compartidas a través de posts y videos. Primero, vamos a examinar la estructura de tabla:
posts id - integer name - string videos id - integer name - string tags id - integer name - string taggables tag_id - integer taggable_id - integer taggable_type - string
Estructura del modelo
Seguidamente, estamos listos para definir las relaciones en el modelo. Ambos modelos Post
y Video
tendrán un método tags
que ejecuta el método morphToMany
en la clase base de Eloquent:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Post extends Model { /** * Get all of the tags for the post. */ public function tags() { return $this->morphToMany('App\Tag', 'taggable'); } }
Definiendo el inverso de la relación
A continuación, en el modelo Tag
, debes definir un método para cada uno de sus modelos relacionados. Así, para este ejemplo, definiremos un método posts
y un método videos
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Tag extends Model { /** * Get all of the posts that are assigned this tag. */ public function posts() { return $this->morphedByMany('App\Post', 'taggable'); } /** * Get all of the videos that are assigned this tag. */ public function videos() { return $this->morphedByMany('App\Video', 'taggable'); } }
Obteniendo la relación
Una vez que tu tabla en la base de datos y modelos son definidos, puedes acceder a las relaciones mediante tus modelos. Por ejemplo, para acceder a todos los tags de un post, puedes usar la propiedad dinámica tags
:
$post = App\Post::find(1); foreach ($post->tags as $tag) { // }
También puedes obtener el propietario de una relación polimórfica desde el modelo polimórfico accediendo al nombre del método que realiza la llamada a morphedByMany
. En nuestro caso, estos son los métodos posts
o videos
en el modelo Tag
. Así, accederemos a esos métodos como propiedades dinámicas:
$tag = App\Tag::find(1); foreach ($tag->videos as $video) { // }
Tipos polimórficos personalizados
Por defecto, Laravel usará el nombre completo de clase para almacenar el tipo del modelo relacionado. Por ejemplo, dado el ejemplo uno-a-muchos de arriba donde un Comment
puede pertenecer a un Post
o a un Video
, el commentable_type
por defecto será App\Post
o App\Video
, respectivamente. Sin embargo, puedes querer desacoplar tu base de datos de la estructura interna de tu aplicación. En dicho caso, puedes definir un «mapa de morfología (morph map)» para indicarle a Eloquent que use un nombre personalizado para cada modelo en lugar del nombre de la clase:
use Illuminate\Database\Eloquent\Relations\Relation; Relation::morphMap([ 'posts' => 'App\Post', 'videos' => 'App\Video', ]);
Puedes registrar el morphMap
en la función boot
de tu AppServiceProvider
o crear un Service Provider independiente si lo deseas.
Al agregar un «morph map» a tu aplicación existente, cada valor de la columna de morfología *_type
en tu base de datos que aún contenga una clase completamente calificada necesitará ser convertida a su nombre de «mapa».
Consultando relaciones
Ya que todos los tipos de relaciones Eloquent son definidas por medio de métodos, puedes ejecutar esos métodos para obtener una instancia de la relación sin ejecutar realmente las consultas de la relación. Además, todos los tipos de relaciones Eloquent también sirven como constructores de consultas, permitiendo que continúes encadenando restricciones dentro de la consulta de la relación antes de ejecutar finalmente el SQL contra la base de datos.
Por ejemplo, imagina un sistema de blog en el cual un modelo User
tiene muchos modelos Post
asociados:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class User extends Model { /** * Get all of the posts for the user. */ public function posts() { return $this->hasMany('App\Post'); } }
Puedes consultar la relación posts
y agregar limitaciones a la relación de la siguiente forma:
$user = App\User::find(1); $user->posts()->where('active', 1)->get();
Puedes usar cualquiera de los métodos de constructor de consultas en la relación, así que asegúrate de revisar la documentación del constructor de consultas para aprender sobre todos los métodos disponibles.
Encadenando cláusulas orWhere
en relaciones
Como se demostró en el ejemplo superior, eres libre de agregar restriciones adicionales a las relaciones al momento de realizar peticiones. Sin embargo, ten cuidado al encadenar cláusulas orWhere
a una relación, dado que las cláusulas orWhere
serán agrupadas lógicamente en el mismo nivel que la restricción de la relación:
$user->posts() ->where('active', 1) ->orWhere('votes', '>=', 100) ->get(); // select * from posts // where user_id = ? and active = 1 or votes >= 100
En la mayoría de los casos, probablemente pretendes usar grupos de restricciones para agrupar lógicamente las comprobaciones condicionales entre paréntesis:
use Illuminate\Database\Eloquent\Builder; $user->posts() ->where(function (Builder $query) { return $query->where('active', 1) ->orWhere('votes', '>=', 100); }) ->get(); // select * from posts // where user_id = ? and (active = 1 or votes >= 100)
Métodos de relación Vs. propiedades dinámicas
Si no necesitas agregar restricciones adicionales a una consulta de relación de Eloquent, puedes acceder a la relación como si fuera una propiedad. Por ejemplo, continuando con el uso de nuestros modelos de ejemplo User
y Post
, podemos acceder a todos los posts de un usuario como sigue:
$user = App\User::find(1); foreach ($user->posts as $post) { // }
Las propiedades dinámicas son de «carga diferida (lazy loading)», lo que significa que cargarán solamente los datos de su relación cuando realmente accedas a ellas. Debido a esto, los desarrolladores con frecuencia usan carga previa (eager loading) para precargar las relaciones que ellos saben que serán accedidas después de cargar el modelo. La carga previa proporciona una reducción significativa en consultas SQL que deben ser ejecutadas para cargar las relaciones de un modelo.
Consultando la existencia de una relación
Cuando accedes a los registros de un modelo, puedes desear limitar sus resultados basados en la existencia de una relación. Por ejemplo, imagina que quieres obtener todos los posts de blog que tienen al menos un comentario. Para hacer eso, puedes pasar el nombre de la relación a los métodos has
y orHas
:
// Retrieve all posts that have at least one comment... $posts = App\Post::has('comments')->get();
También puedes especificar un operador y la cantidad para personalizar aún más la consulta:
// Retrieve all posts that have three or more comments... $posts = App\Post::has('comments', '>=', 3)->get();
Las instrucciones has
anidadas también pueden ser construidas usando la notación de «punto». Por ejemplo, puedes obtener todos los posts que tienen al menos un comentario con votos:
// Retrieve posts that have at least one comment with votes... $posts = App\Post::has('comments.votes')->get();
Incluso si necesitas más potencia, puedes usar los métodos whereHas
y orWhereHas
para poner condiciones «where» en tus consultas has
. Estos métodos permiten que agregues restricciones personalizadas a una restricción de relación, tal como verificar el contenido de un comentario:
use Illuminate\Database\Eloquent\Builder; // Retrieve posts with at least one comment containing words like foo%... $posts = App\Post::whereHas('comments', function (Builder $query) { $query->where('content', 'like', 'foo%'); })->get(); // Retrieve posts with at least ten comments containing words like foo%... $posts = App\Post::whereHas('comments', function (Builder $query) { $query->where('content', 'like', 'foo%'); }, '>=', 10)->get();
Consultando la ausencia de una relación
Al momento de acceder a los registros de un modelo, puedes desear limitar tus resultados en base a la ausencia de una relación. Por ejemplo, imagina que quieras obtener todos los posts de blogs que no tienen algún comentario. Para hacer eso, puedes pasar el nombre de la relación a los métodos doesntHave
y orDoesntHave
:
$posts = App\Post::doesntHave('comments')->get();
Incluso si necesitas más potencia, puedes usar los métodos whereDoesntHave
y orWhereDoesntHave
para poner condiciones «where» en tus consultas doesntHave
. Estos métodos permiten que agregues restricciones personalizadas a una restricción de relación, tal como verificar el contenido de un comentario:
use Illuminate\Database\Eloquent\Builder; $posts = App\Post::whereDoesntHave('comments', function (Builder $query) { $query->where('content', 'like', 'foo%'); })->get();
Puedes usar notación «de puntos» para ejecutar una consulta contra una relación anidada. Por ejemplo, la siguiente consulta entregará todos los posts con comentarios de autores que no están vetados:
use Illuminate\Database\Eloquent\Builder; $posts = App\Post::whereDoesntHave('comments.author', function (Builder $query) { $query->where('banned', 0); })->get();
Consultando relaciones polimórficas
Para consultar la existencia de relaciones MorphTo
, puedes usar el método whereHasMorph
y sus métodos correspondientes:
use Illuminate\Database\Eloquent\Builder; // Retrieve comments associated to posts or videos with a title like foo%... $comments = App\Comment::whereHasMorph( 'commentable', ['App\Post', 'App\Video'], function (Builder $query) { $query->where('title', 'like', 'foo%'); } )->get(); // Retrieve comments associated to posts with a title not like foo%... $comments = App\Comment::whereDoesntHaveMorph( 'commentable', 'App\Post', function (Builder $query) { $query->where('title', 'like', 'foo%'); } )->get();
Puedes usar el parametro $type
para agregar diferentes restricciones dependiendo del modelo relacionado:
use Illuminate\Database\Eloquent\Builder; $comments = App\Comment::whereHasMorph( 'commentable', ['App\Post', 'App\Video'], function (Builder $query, $type) { $query->where('title', 'like', 'foo%'); if ($type === 'App\Post') { $query->orWhere('content', 'like', 'foo%'); } } )->get();
En lugar de pasar un arreglo de posibles modelos polimórficos, puedes proporcionar un *
como comodín y dejar que Laravel retorne todos los posibles tipos polimórficos desde la base de datos. Laravel ejecutará una solicitud adicional para poder realizar esta operación:
use Illuminate\Database\Eloquent\Builder; $comments = App\Comment::whereHasMorph('commentable', '*', function (Builder $query) { $query->where('title', 'like', 'foo%'); })->get();
Contando modelos relacionados
Si quieres contar el número de resultados de una relación sin cargarlos realmente puedes usar el método withCount
, el cual coloca una columna {relation}_count
en tus modelos resultantes. Por ejemplo:
$posts = App\Post::withCount('comments')->get(); foreach ($posts as $post) { echo $post->comments_count; }
Puedes agregar las «cuentas» para múltiples relaciones así como también agregar restricciones a las consultas:
use Illuminate\Database\Eloquent\Builder; $posts = App\Post::withCount(['votes', 'comments' => function (Builder $query) { $query->where('content', 'like', 'foo%'); }])->get(); echo $posts[0]->votes_count; echo $posts[0]->comments_count;
También puedes poner un alias al resultado de la cuenta de la relación, permitiendo múltiples cuentas en la misma relación:
use Illuminate\Database\Eloquent\Builder; $posts = App\Post::withCount([ 'comments', 'comments as pending_comments_count' => function (Builder $query) { $query->where('approved', false); }, ])->get(); echo $posts[0]->comments_count; echo $posts[0]->pending_comments_count;
Si estás combinando withCount
con una instrucción select
, asegúrate de llamar a withCount
después del método select
:
$posts = App\Post::select(['title', 'body'])->withCount('comments')->get(); echo $posts[0]->title; echo $posts[0]->body; echo $posts[0]->comments_count;
Además, utilizando el método loadCount
, puedes cargar un conteo de la relación después de que el modelo padre haya sido obtenido:
$book = App\Book::first(); $book->loadCount('genres');
Si necesitas establecer restricciones adicionales de consulta en la consulta de carga previa, puedes pasar un arreglo asociativo cuyas claves serán las relaciones que deseas cargar. Los valores del arreglo deben ser instancias de Closure
que reciben la instancia del generador de consulta:
$book->loadCount(['reviews' => function ($query) { $query->where('rating', 5); }])
Carga previa (eager loading)
Al momento de acceder a las relaciones Eloquent como propiedades, los datos de la relación son «cargados diferidamente (lazy loading)». Esto significa que los datos de la relación no son cargados realmente hasta que primero accedas a la propiedad. Sin embargo, Eloquent puede «cargar previamente (eager loading)» las relaciones al mismo tiempo que consultas el modelo padre. La carga previa alivia el problema de la consulta N + 1. Para ilustrar el problema de la consulta N + 1, considera un modelo Book
que está relacionado a Author
:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model { /** * Get the author that wrote the book. */ public function author() { return $this->belongsTo('App\Author'); } }
Ahora, vamos a obtener todos los libros y sus autores:
$books = App\Book::all(); foreach ($books as $book) { echo $book->author->name; }
Este ciclo ejecutará una consulta para obtener todos los libros en la tabla, después otra consulta para cada libro para obtener el autor. Así, si tenemos 25 libros, este ciclo debería ejecutar 26 consultas: 1 para el libro original y 25 consultas adicionales para obtener el autor de cada libro.
Afortunadamente, podemos usar la carga previa para reducir esta operación a solo 2 consultas. Al momento de consultar, puedes especificar cuáles relaciones deberían ser precargadas usando el método with
:
$books = App\Book::with('author')->get(); foreach ($books as $book) { echo $book->author->name; }
Para esta operación, solo dos consultas serán ejecutadas:
select * from books select * from authors where id in (1, 2, 3, 4, 5, ...)
Carga previa de múltiples relaciones
Algunas veces puedes necesitar la carga previa de varias relaciones diferentes en una operación única. Para hacer eso, pasa sólo los argumentos adicionales al método with
:
$books = App\Book::with(['author', 'publisher'])->get();
Carga previa anidada
Para precargar relaciones anidadas, puedes usar la sintaxis de «punto». Por ejemplo, vamos a precargar todos los autores de los libros y todos los contactos personales del autor en una instrucción de Eloquent:
$books = App\Book::with('author.contacts')->get();
Carga previa anidada de relaciones morphTo
Si deseas cargar previamente una relación morphTo
, así como relaciones anidadas en varias entidades que podrían ser retornadas por dicha relación, puedes usar el método with
en combinación con el método morphWith
de la relación morphTo
. Para ayudarte a ilustrar este método, vamos a considerar el siguiente modelo:
<?php use Illuminate\Database\Eloquent\Model; class ActivityFeed extends Model { /** * Get the parent of the activity feed record. */ public function parentable() { return $this->morphTo(); } }
En este ejemplo, vamos a asumir que los modelos Event
, Photo
y Post
pueden crear modelos ActivityFeed
. Adicionalmente, vamos a asumir que los modelos Event
pertenecen a un modelo Calendar
, que los modelos Photo
están asociados con modelos Tag
, y los modelos Post
pertenecen a un modelo Author
.
Usando estas definiciones de modelos y relaciones, podemos retornar instancias del modelo ActivityFeed
y cargar previamente todos los modelos parentable
y sus respectivas relaciones anidadas:
use Illuminate\Database\Eloquent\Relations\MorphTo; $activities = ActivityFeed::query() ->with(['parentable' => function (MorphTo $morphTo) { $morphTo->morphWith([ Event::class => ['calendar'], Photo::class => ['tags'], Post::class => ['author'], ]); }])->get();
Cargando previamente columnas específicas
No siempre necesitarás todas las columnas de las relaciones que estás obteniendo. Por esta razón, Eloquent te permite especificar cuáles columnas de la relación te gustaría obtener:
$books = App\Book::with('author:id,name')->get();
Al usar esta característica, siempre debes incluir la columna id
y cualquier columna de clave foránea relevante en la lista de columnas que desees retornar.
Carga previa por defecto
Algunas veces podrías querer cargar siempre algunas relaciones al retornar un modelo. Para lograr esto, puedes definir una propiedad $with
en el modelo:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model { /** * The relationships that should always be loaded. * * @var array */ protected $with = ['author']; /** * Get the author that wrote the book. */ public function author() { return $this->belongsTo('App\Author'); } }
Si te gustaria remover un elemento de la propiedad $with
para una sola petición, puedes usar el método without
:
$books = App\Book::without('author')->get();
Restringiendo cargas previas
Algunas veces puedes desear cargar previamente una relación, pero también especificar condiciones de consulta adicionales para la consulta de carga previa. Aquí está un ejemplo:
$users = App\User::with(['posts' => function ($query) { $query->where('title', 'like', '%first%'); }])->get();
En este ejemplo, Eloquent solamente precargará los posts donde la columna title
del post contenga la palabra first
. Puedes ejecutar otros métodos del constructor de consulta para personalizar más la operación de carga previa:
$users = App\User::with(['posts' => function ($query) { $query->orderBy('created_at', 'desc'); }])->get();
Los métodos del constructor de consultas limit
y take
no se pueden usar al restringir las cargas previas.
Carga previa diferida (lazy eager loading)
Algunas veces puedes necesitar precargar una relación después de que el modelo padre ya ha sido obtenido. Por ejemplo, esto puede ser útil si necesitas decidir dinámicamente si se cargan modelos relacionados:
$books = App\Book::all(); if ($someCondition) { $books->load('author', 'publisher'); }
Si necesitas establecer restricciones de consultas adicionales en la consulta de carga previa, puedes pasar un arreglo asociativo cuyas claves son las relaciones que deseas cargar. Los valores del arreglo deberían ser instancias de Closure
, las cuales reciben la instancia de consulta:
$author->load(['books' => function ($query) { $query->orderBy('published_date', 'asc'); }]);
Para cargar una relación sólo cuando aún no se ha cargado, usa el método loadMissing
:
public function format(Book $book) { $book->loadMissing('author'); return [ 'name' => $book->name, 'author' => $book->author->name, ]; }
Carga previa diferida anidada y morphTo
Si deseas cargar previamente una relación morphTo
, así como relaciones anidadas en las diversas entidades que pueden ser devueltas por esa relación, puedes usar el método loadMorph
.
Este método acepta el nombre de la relación morphTo
como su primer argumento, y un arreglo de pares modelo / relación como su segundo argumento. Para ayudar a ilustrar este método, consideremos el siguiente modelo:
<?php use Illuminate\Database\Eloquent\Model; class ActivityFeed extends Model { /** * Get the parent of the activity feed record. */ public function parentable() { return $this->morphTo(); } }
En este ejemplo, asumamos que los modelos Event
, Photo
y Post
pueden crear modelos ActivityFeed
. Además, supongamos que los modelos Event
pertenecen a un modelo Calendar
, los modelos Photo
están asociados con los modelos Tag
, y los modelos Post
pertenecen a un modelo Author
.
Usando estas definiciones de modelos y relaciones, podemos obtener instancias del modelo ActivityFeed
y cargar previamente todos los modelos parentable
y sus respectivas relaciones anidadas:
$activities = ActivityFeed::with('parentable') ->get() ->loadMorph('parentable', [ Event::class => ['calendar'], Photo::class => ['tags'], Post::class => ['author'], ]);
Insertando y actualizando modelos relacionados
El método save
Eloquent proporciona métodos convenientes para agregar nuevos modelos a las relaciones. Por ejemplo, quizá necesites insertar un nuevo Comment
para un modelo Post
. En lugar de establecer manualmente el atributo post_id
en el Comment
, puedes insertar el Comment
directamente con el método save
de la relación:
$comment = new App\Comment(['message' => 'A new comment.']); $post = App\Post::find(1); $post->comments()->save($comment);
Observa que no accedimos a la relación comments
como una propiedad dinámica. En su lugar, ejecutamos el método comments
para obtener una instancia de la relación. El método save
automáticamente agregará el valor post_id
apropiado al nuevo modelo Comment
.
Si necesitas guardar múltiples modelos relacionados, puedes usar el método saveMany
:
$post = App\Post::find(1); $post->comments()->saveMany([ new App\Comment(['message' => 'A new comment.']), new App\Comment(['message' => 'Another comment.']), ]);
Guardando modelos y relaciones recursivamente
Si quieres hacer save
a tu modelo y a todas sus relaciones asociadas, puedes usar el método push
:
$post = App\Post::find(1); $post->comments[0]->message = 'Message'; $post->comments[0]->author->name = 'Author Name'; $post->push();
El método create
Además de los métodos save
y saveMany
, también puedes usar el método create
, el cual acepta un arreglo de atributos, crea un modelo y lo inserta dentro de la base de datos. Otra vez, la diferencia entre save
y create
es que save
acepta una instancia de modelo Eloquent completa mientras que create
acepta un array
de PHP plano:
$post = App\Post::find(1); $comment = $post->comments()->create([ 'message' => 'A new comment.', ]);
Antes de usar el método create
, asegúrate de revisar la documentación sobre la asignación masiva de atributos.
Puedes usar el método createMany
para crear múltiples modelos relacionados:
$post = App\Post::find(1); $post->comments()->createMany([ [ 'message' => 'A new comment.', ], [ 'message' => 'Another new comment.', ], ]);
También puedes usar los métodos findOrNew
, firstOrNew
, firstOrCreate
y updateOrCreate
para crear y actualizar modelos en relaciones.
Actualizar relación pertenece a (belongsTo)
Al momento de actualizar una relación belongsTo
, puedes usar el método associate
. Este método establecerá la clave foránea en el modelo hijo:
$account = App\Account::find(10); $user->account()->associate($account); $user->save();
Al momento de eliminar una relación belongsTo
, puedes usar el método dissociate
. Este método establecerá la clave foránea de la relación a null
:
$user->account()->dissociate(); $user->save();
Modelos predeterminados
Las relaciones belongsTo
, hasOne
, hasOneThrough
y morphOne
te permiten definir un modelo predeterminado que se devolverá si la relación dada es null
. A este patrón se le conoce comúnmente como patrón Null Object y puede ayudar a quitar comprobaciones condicionales en tu código. En el ejemplo siguiente, la relación user
devolverá un modelo App\User
vacío si no hay un user
adjunto a la publicación:
/** * Get the author of the post. */ public function user() { return $this->belongsTo('App\User')->withDefault(); }
Para rellenar el modelo predeterminado con atributos, puedes pasar un arreglo o Closure al método withDefault
:
/** * Get the author of the post. */ public function user() { return $this->belongsTo('App\User')->withDefault([ 'name' => 'Guest Author', ]); } /** * Get the author of the post. */ public function user() { return $this->belongsTo('App\User')->withDefault(function ($user, $post) { $user->name = 'Guest Author'; }); }
Relaciones muchos a muchos
Adjuntando (attach) / Quitando (detach)
Eloquent también proporciona algunos métodos helper adicionales para hacer que el trabajo con los modelos relacionados sea más conveniente. Por ejemplo, vamos a imaginar que un usuario tiene muchos roles y un rol puede tener muchos usuarios. Para adjuntar un rol a un usuario insertando un registro en la tabla intermedia que vincula los modelos, usa el método attach
:
$user = App\User::find(1); $user->roles()->attach($roleId);
Al momento de adjuntar una relación a un modelo, también puedes pasar un arreglo de datos adicionales para ser insertados dentro de la tabla intermedia:
$user->roles()->attach($roleId, ['expires' => $expires]);
Algunas veces puede ser necesario quitar un rol de un usuario. Para remover un registro de una relación de muchos-a-muchos, usa el método detach
. El método detach
eliminará el registro apropiado de la tabla intermedia; sin embargo, ambos modelos permanecerán en la base de datos:
// Detach a single role from the user... $user->roles()->detach($roleId); // Detach all roles from the user... $user->roles()->detach();
Por conveniencia, attach
y detach
también aceptan arreglos de IDs como entrada:
$user = App\User::find(1); $user->roles()->detach([1, 2, 3]); $user->roles()->attach([ 1 => ['expires' => $expires], 2 => ['expires' => $expires], ]);
Sincronizando asociaciones
También puedes usar el método sync
para construir asociaciones muchos-a-muchos. El método sync
acepta un arreglo de IDs para colocar en la tabla intermedia. Algunos IDs que no estén en el arreglo dado serán removidos de la tabla intermedia. Por tanto, después que esta operación se complete, solamente los IDs en el arreglo dado existirán en la tabla intermedia:
$user->roles()->sync([1, 2, 3]);
También puedes pasar valores adicionales de tabla intermedia con los IDs:
$user->roles()->sync([1 => ['expires' => true], 2, 3]);
Si no quieres quitar los IDs existentes, puedes usar el método syncWithoutDetaching
:
$user->roles()->syncWithoutDetaching([1, 2, 3]);
Alternar asociaciones
La relación de muchos-a-muchos también proporciona un método toggle
el cual «alterna» el estado adjunto de los IDs dados. Si el ID está actualmente adjuntado, será removido. De igual forma, si está actualmente removido, será adjuntado:
$user->roles()->toggle([1, 2, 3]);
Guardando datos adicionales en una tabla pivote
Al momento de trabajar con una relación de muchos-a-muchos, el método save
acepta un arreglo de atributos adicionales de tabla intermedia como su segundo argumento:
App\User::find(1)->roles()->save($role, ['expires' => $expires]);
Actualizando un registro en una tabla pivote
Si necesitas actualizar una fila existente en tu tabla pivote, puedes usar el método updateExistingPivot
. Este método acepta la clave foránea del registro pivote y un arreglo de atributos para actualizar:
$user = App\User::find(1); $user->roles()->updateExistingPivot($roleId, $attributes);
Tocando marcas de tiempo del padre
Cuando un modelo belongsTo
o belongsToMany
a otro modelo, tal como un Comment
el cual pertenece a un Post
, algunas veces es útil actualizar la marca de tiempo del padre cuando el modelo hijo es actualizado. Por ejemplo, cuando un modelo Comment
es actualizado, puedes querer «tocar» automáticamente la marca de tiempo updated_at
del Post
que lo posee. Eloquent hace esto fácil. Simplemente agrega una propiedad touches
conteniendo los nombres de las relaciones al modelo hijo:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Comment extends Model { /** * All of the relationships to be touched. * * @var array */ protected $touches = ['post']; /** * Get the post that the comment belongs to. */ public function post() { return $this->belongsTo('App\Post'); } }
Ahora, cuando actualices un Comment
, el Post
que lo posee tendrá su columna updated_at
actualizada también, haciéndolo más conveniente para saber cuándo invalidar una caché del modelo Post
:
$comment = App\Comment::find(1); $comment->text = 'Edit to this comment!'; $comment->save();
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Eloquent: Primeros Pasos - Documentación de Laravel 6 Lección siguiente Eloquent: Colecciones - Documentación de Laravel 6