1. Eloquent ORM
  2. Eloquent: Serialización

Introducción

Al construir APIs utilizando Laravel, a menudo necesitarás convertir tus modelos y relaciones a matrices o JSON. Eloquent incluye métodos convenientes para realizar estas conversiones, así como para controlar qué atributos se incluyen en la representación serializada de tus modelos.

Nota Para una forma aún más robusta de manejar la serialización JSON de modelos y colecciones Eloquent, consulta la documentación sobre Recursos API de Eloquent.

Serialización de Modelos y Colecciones

Serialización a Matrices

Para convertir un modelo y sus relaciones cargadas a una matriz, debes utilizar el método toArray. Este método es recursivo, por lo que se convertirán a matrices todos los atributos y todas las relaciones (incluidas las relaciones de relaciones):

use App\Models\User;
 
$user = User::with('roles')->first();
 
return $user->toArray();

El método attributesToArray se puede utilizar para convertir los atributos de un modelo a una matriz, pero no sus relaciones:

$user = User::first();
 
return $user->attributesToArray();

También puedes convertir colecciones completas de modelos a matrices llamando al método toArray en la instancia de la colección:

$users = User::all();
 
return $users->toArray();

Serialización a JSON

Para convertir un modelo a JSON, debes utilizar el método toJson. Al igual que toArray, el método toJson es recursivo, por lo que se convertirán a JSON todos los atributos y relaciones. También puedes especificar cualquier opción de codificación JSON que sea compatible con PHP:

use App\Models\User;
 
$user = User::find(1);
 
return $user->toJson();
 
return $user->toJson(JSON_PRETTY_PRINT);

Alternativamente, puedes convertir un modelo o colección a una cadena, lo que llamará automáticamente al método toJson en el modelo o colección:

return (string) User::find(1);

Dado que los modelos y las colecciones se convierten a JSON al ser convertidos a una cadena, puedes devolver objetos Eloquent directamente desde las rutas o controladores de tu aplicación. Laravel serializará automáticamente tus modelos y colecciones Eloquent a JSON cuando se devuelvan desde rutas o controladores:

Route::get('users', function () {
return User::all();
});

Relaciones

Cuando un modelo Eloquent se convierte a JSON, sus relaciones cargadas se incluirán automáticamente como atributos en el objeto JSON. Además, aunque los métodos de relaciones Eloquent se definen utilizando nombres de métodos en "camel case", el atributo JSON de una relación será en "snake case".

Ocultar Atributos de JSON

A veces puede que desees limitar los atributos, como las contraseñas, que se incluyen en la representación de matriz o JSON de tu modelo. Para hacerlo, añade una propiedad $hidden a tu modelo. Los atributos que estén en la matriz $hidden no se incluirán en la representación serializada de tu modelo:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Los atributos que deben estar ocultos en matrices.
*
* @var array
*/
protected $hidden = ['password'];
}

Nota Para ocultar relaciones, añade el nombre del método de la relación a la propiedad $hidden de tu modelo Eloquent.

Alternativamente, puedes utilizar la propiedad visible para definir una "lista permitida" de atributos que deben incluirse en la representación de matriz y JSON de tu modelo. Todos los atributos que no estén presentes en la matriz $visible se ocultarán cuando el modelo se convierta a una matriz o JSON:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Los atributos que deben ser visibles en matrices.
*
* @var array
*/
protected $visible = ['first_name', 'last_name'];
}

Modificación Temporal de la Visibilidad del Atributo

Si deseas hacer visibles algunos atributos normalmente ocultos en una instancia de modelo dada, puedes utilizar el método makeVisible. El método makeVisible devuelve la instancia del modelo:

return $user->makeVisible('attribute')->toArray();

Del mismo modo, si deseas ocultar algunos atributos que son normalmente visibles, puedes utilizar el método makeHidden.

return $user->makeHidden('attribute')->toArray();

Si deseas anular temporalmente todos los atributos visibles u ocultos, puedes utilizar los métodos setVisible y setHidden respectivamente:

return $user->setVisible(['id', 'name'])->toArray();
 
return $user->setHidden(['email', 'password', 'remember_token'])->toArray();

Añadir Valores a JSON

Ocasionalmente, al convertir modelos a matrices o JSON, es posible que desees añadir atributos que no tienen una columna correspondiente en tu base de datos. Para hacerlo, primero define un accesor para el valor:

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Determinar si el usuario es un administrador.
*/
protected function isAdmin(): Attribute
{
return new Attribute(
get: fn () => 'yes',
);
}
}

Si deseas que el accesor siempre se añada a la representación de matriz y JSON de tu modelo, puedes añadir el nombre del atributo a la propiedad appends de tu modelo. Ten en cuenta que los nombres de atributos se referencian típicamente utilizando su representación serializada en "snake case", aunque el método PHP del accesor se define utilizando "camel case":

<?php
 
namespace App\Models;
 
use Illuminate\Database\Eloquent\Model;
 
class User extends Model
{
/**
* Los accesores para añadir al formulario de matriz del modelo.
*
* @var array
*/
protected $appends = ['is_admin'];
}

Una vez que el atributo ha sido añadido a la lista appends, se incluirá tanto en la representación de matriz como en la de JSON del modelo. Los atributos en la matriz appends también respetarán las configuraciones visible y hidden del modelo.

Añadir Dinámicamente en Tiempo de Ejecución

En tiempo de ejecución, puedes indicar a una instancia del modelo que añada atributos adicionales mediante el método append. O puedes utilizar el método setAppends para anular toda la matriz de propiedades añadidas para una instancia de modelo dada:

return $user->append('is_admin')->toArray();
 
return $user->setAppends(['is_admin'])->toArray();

Serialización de Fechas

Personalización del Formato de Fecha Predeterminado

Puedes personalizar el formato predeterminado de serialización anulando el método serializeDate. Este método no afecta la forma en que se formatean tus fechas para almacenarlas en la base de datos:

/**
* Preparar una fecha para la serialización a matriz / JSON.
*/
protected function serializeDate(DateTimeInterface $date): string
{
return $date->format('Y-m-d');
}

Personalización del Formato de Fecha por Atributo

Puedes personalizar el formato de serialización de atributos de fecha Eloquent individuales especificando el formato de fecha en las declaraciones de casting del modelo:

protected $casts = [
'birthday' => 'date:Y-m-d',
'joined_at' => 'datetime:Y-m-d H:00',
];