Estamos actualizando el sitio. Durante unos días es posible que veas fallos de diseño o de traducción. La documentación sigue disponible: si una página se ve mal, recárgala más tarde.

Inicio Laravel 10.x Eloquent: Mutadores & Casting

Eloquent: Mutadores & Casting

10.x 7 de mar. de 2026

#Introducción

Los accessors, mutators y la conversión de atributos permiten transformar los valores de los atributos de Eloquent cuando los recupera o establece en instancias del modelo. Por ejemplo, puede que quiera usar el encrypter de Laravel para encriptar un valor mientras se almacena en la base de datos, y luego desencriptar automáticamente el atributo cuando lo acceda en un modelo Eloquent. O puede que quiera convertir una cadena JSON almacenada en su base de datos a un array cuando se accede a través de su modelo Eloquent.

#Accessors y Mutators

#Definiendo un Accessor

Un accessor transforma el valor de un atributo Eloquent cuando se accede a él. Para definir un accessor, cree un método protegido en su modelo que represente el atributo accesible. El nombre de este método debe corresponder a la representación en "camel case" del verdadero atributo subyacente del modelo / columna de la base de datos cuando sea aplicable.

En este ejemplo, definiremos un accessor para el atributo first_name. El accessor será llamado automáticamente por Eloquent cuando se intente obtener el valor del atributo first_name. Todos los métodos accessor / mutator deben declarar un tipo de retorno Illuminate\Database\Eloquent\Casts\Attribute:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Obtener el primer nombre del usuario.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
        );
    }
}

Todos los métodos accessor retornan una instancia de Attribute que define cómo se accederá al atributo y, opcionalmente, cómo se mutará. En este ejemplo, solo definimos cómo se accederá al atributo. Para ello, proporcionamos el argumento get al constructor de la clase Attribute.

Como puede ver, el valor original de la columna se pasa al accessor, permitiéndole manipular y devolver el valor. Para acceder al valor del accessor, simplemente puede acceder al atributo first_name en una instancia del modelo:

use App\Models\User;

$user = User::find(1);

$firstName = $user->first_name;
Примечание

Si desea que estos valores calculados se agreguen a las representaciones en array / JSON de su modelo, deberá agregarlos.

#Construyendo Objetos de Valor desde Múltiples Atributos

A veces su accessor puede necesitar transformar múltiples atributos del modelo en un único "objeto de valor". Para ello, su cierre get puede aceptar un segundo argumento $attributes, que se suministrará automáticamente al cierre y contendrá un array con todos los atributos actuales del modelo:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

/**
 * Interactuar con la dirección del usuario.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    );
}

#Caché de Accessors

Cuando se retornan objetos de valor desde accessors, cualquier cambio realizado en el objeto de valor se sincronizará automáticamente con el modelo antes de que se guarde. Esto es posible porque Eloquent retiene las instancias retornadas por los accessors para poder devolver la misma instancia cada vez que se invoca el accessor:

use App\Models\User;

$user = User::find(1);

$user->address->lineOne = 'Valor Actualizado de Línea 1 de Dirección';
$user->address->lineTwo = 'Valor Actualizado de Línea 2 de Dirección';

$user->save();

Sin embargo, a veces puede querer habilitar la caché para valores primitivos como strings y booleanos, especialmente si son computacionalmente intensivos. Para lograr esto, puede invocar el método shouldCache al definir su accessor:

protected function hash(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => bcrypt(gzuncompress($value)),
    )->shouldCache();
}

Si desea deshabilitar el comportamiento de caché de objetos de los atributos, puede invocar el método withoutObjectCaching al definir el atributo:

/**
 * Interactuar con la dirección del usuario.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
    )->withoutObjectCaching();
}

#Definiendo un Mutator

Un mutator transforma el valor de un atributo Eloquent cuando se establece. Para definir un mutator, puede proporcionar el argumento set al definir su atributo. Definamos un mutator para el atributo first_name. Este mutator será llamado automáticamente cuando intentemos establecer el valor del atributo first_name en el modelo:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Interactuar con el primer nombre del usuario.
     */
    protected function firstName(): Attribute
    {
        return Attribute::make(
            get: fn (string $value) => ucfirst($value),
            set: fn (string $value) => strtolower($value),
        );
    }
}

El cierre mutator recibirá el valor que se está estableciendo en el atributo, permitiéndole manipular el valor y devolver el valor manipulado. Para usar nuestro mutator, solo necesitamos establecer el atributo first_name en un modelo Eloquent:

use App\Models\User;

$user = User::find(1);

$user->first_name = 'Sally';

En este ejemplo, el callback set será llamado con el valor Sally. El mutator aplicará la función strtolower al nombre y establecerá su valor resultante en el array interno $attributes del modelo.

#Mutando Múltiples Atributos

A veces su mutator puede necesitar establecer múltiples atributos en el modelo subyacente. Para ello, puede retornar un array desde el cierre set. Cada clave del array debe corresponder con un atributo subyacente / columna de base de datos asociada con el modelo:

use App\Support\Address;
use Illuminate\Database\Eloquent\Casts\Attribute;

/**
 * Interactuar con la dirección del usuario.
 */
protected function address(): Attribute
{
    return Attribute::make(
        get: fn (mixed $value, array $attributes) => new Address(
            $attributes['address_line_one'],
            $attributes['address_line_two'],
        ),
        set: fn (Address $value) => [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ],
    );
}

#Conversión de Atributos

La conversión de atributos proporciona una funcionalidad similar a los accessors y mutators sin requerir que defina métodos adicionales en su modelo. En cambio, la propiedad $casts de su modelo ofrece un método conveniente para convertir atributos a tipos de datos comunes.

La propiedad $casts debe ser un array donde la clave es el nombre del atributo que se va a convertir y el valor es el tipo al que desea convertir la columna. Los tipos de conversión soportados son:

  • array
  • AsStringable::class
  • boolean
  • collection
  • date
  • datetime
  • immutable_date
  • immutable_datetime
  • decimal:<precision>
  • double
  • encrypted
  • encrypted:array
  • encrypted:collection
  • encrypted:object
  • float
  • hashed
  • integer
  • object
  • real
  • string
  • timestamp

Para demostrar la conversión de atributos, vamos a convertir el atributo is_admin, que se almacena en nuestra base de datos como un entero (0 o 1), a un valor booleano:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Los atributos que deben ser convertidos.
     *
     * @var array
     */
    protected $casts = [
        'is_admin' => 'boolean',
    ];
}

Después de definir la conversión, el atributo is_admin siempre será convertido a booleano cuando lo acceda, incluso si el valor subyacente está almacenado en la base de datos como un entero:

$user = App\Models\User::find(1);

if ($user->is_admin) {
    // ...
}

Si necesita agregar una nueva conversión temporal en tiempo de ejecución, puede usar el método mergeCasts. Estas definiciones de conversión se agregarán a las conversiones ya definidas en el modelo:

$user->mergeCasts([
    'is_admin' => 'integer',
    'options' => 'object',
]);
Внимание

Los atributos que son null no serán convertidos. Además, nunca debe definir una conversión (o un atributo) que tenga el mismo nombre que una relación o asignar una conversión a la clave primaria del modelo.

#Conversión a Stringable

Puede usar la clase de conversión Illuminate\Database\Eloquent\Casts\AsStringable para convertir un atributo del modelo a un objeto fluent Illuminate\Support\Stringable:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Casts\AsStringable;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Los atributos que deben ser convertidos.
     *
     * @var array
     */
    protected $casts = [
        'directory' => AsStringable::class,
    ];
}

#Conversión a Array y JSON

La conversión array es especialmente útil cuando se trabaja con columnas almacenadas como JSON serializado. Por ejemplo, si su base de datos tiene un campo de tipo JSON o TEXT que contiene JSON serializado, agregar la conversión array a ese atributo deserializará automáticamente el atributo a un array PHP cuando lo acceda en su modelo Eloquent:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Los atributos que deben ser convertidos.
     *
     * @var array
     */
    protected $casts = [
        'options' => 'array',
    ];
}

Una vez definida la conversión, puede acceder al atributo options y este será deserializado automáticamente de JSON a un array PHP. Cuando establezca el valor del atributo options, el array dado será serializado automáticamente de nuevo a JSON para su almacenamiento:

use App\Models\User;

$user = User::find(1);

$options = $user->options;

$options['key'] = 'value';

$user->options = $options;

$user->save();

Para actualizar un solo campo de un atributo JSON con una sintaxis más concisa, puede hacer que el atributo sea asignable en masa y usar el operador -> al llamar al método update:

$user = User::find(1);

$user->update(['options->key' => 'value']);

#Conversión a ArrayObject y Collection

Aunque la conversión estándar array es suficiente para muchas aplicaciones, tiene algunas desventajas. Dado que la conversión array retorna un tipo primitivo, no es posible mutar directamente un offset del array. Por ejemplo, el siguiente código generará un error en PHP:

$user = User::find(1);

$user->options['key'] = $value;

Para resolver esto, Laravel ofrece una conversión AsArrayObject que convierte su atributo JSON a una clase ArrayObject. Esta característica se implementa usando la implementación de conversión personalizada de Laravel, que permite a Laravel almacenar en caché y transformar inteligentemente el objeto mutado para que se puedan modificar offsets individuales sin generar un error en PHP. Para usar la conversión AsArrayObject, simplemente asígnela a un atributo:

use Illuminate\Database\Eloquent\Casts\AsArrayObject;

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'options' => AsArrayObject::class,
];

De manera similar, Laravel ofrece una conversión AsCollection que convierte su atributo JSON a una instancia de Laravel Collection:

use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'options' => AsCollection::class,
];

Si desea que la conversión AsCollection instancie una clase de colección personalizada en lugar de la clase base de colección de Laravel, puede proporcionar el nombre de la clase de colección como argumento de la conversión:

use App\Collections\OptionCollection;
use Illuminate\Database\Eloquent\Casts\AsCollection;

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'options' => AsCollection::class.':'.OptionCollection::class,
];

#Conversión de Fechas

Por defecto, Eloquent convertirá las columnas created_at y updated_at a instancias de Carbon, que extiende la clase PHP DateTime y proporciona un conjunto de métodos útiles. Puede convertir atributos de fecha adicionales definiendo conversiones de fecha adicionales dentro del array $casts de su modelo. Normalmente, las fechas deben convertirse usando los tipos datetime o immutable_datetime.

Al definir una conversión date o datetime, también puede especificar el formato de la fecha. Este formato se usará cuando el modelo se serialice a un array o JSON:

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'created_at' => 'datetime:Y-m-d',
];

Cuando una columna se convierte como fecha, puede establecer el valor del atributo correspondiente del modelo a un timestamp UNIX, cadena de fecha (Y-m-d), cadena de fecha y hora, o una instancia DateTime / Carbon. El valor de la fecha será convertido correctamente y almacenado en su base de datos.

Puede personalizar el formato de serialización predeterminado para todas las fechas de su modelo definiendo un método serializeDate en su modelo. Este método no afecta cómo se formatean las fechas para su almacenamiento en la base de datos:

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

Para especificar el formato que se debe usar al almacenar realmente las fechas de un modelo en su base de datos, debe definir una propiedad $dateFormat en su modelo:

/**
 * El formato de almacenamiento de las columnas de fecha del modelo.
 *
 * @var string
 */
protected $dateFormat = 'U';

#Conversión de Fechas, Serialización y Zonas Horarias

Por defecto, las conversiones date y datetime serializarán las fechas a una cadena ISO-8601 UTC (YYYY-MM-DDTHH:MM:SS.uuuuuuZ), independientemente de la zona horaria especificada en la opción de configuración timezone de su aplicación. Se recomienda encarecidamente usar siempre este formato de serialización, así como almacenar las fechas de su aplicación en la zona horaria UTC sin cambiar la opción timezone de su aplicación de su valor predeterminado UTC. Usar consistentemente la zona horaria UTC en toda su aplicación proporcionará el máximo nivel de interoperabilidad con otras librerías de manipulación de fechas escritas en PHP y JavaScript.

Si se aplica un formato personalizado a la conversión date o datetime, como datetime:Y-m-d H:i:s, la zona horaria interna de la instancia Carbon se usará durante la serialización de la fecha. Normalmente, esta será la zona horaria especificada en la opción de configuración timezone de su aplicación.

#Conversión de Enum

Eloquent también le permite convertir los valores de sus atributos a Enums de PHP. Para lograr esto, puede especificar el atributo y el enum al que desea convertir en el array $casts de su modelo:

use App\Enums\ServerStatus;

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'status' => ServerStatus::class,
];

Una vez que haya definido la conversión en su modelo, el atributo especificado será convertido automáticamente hacia y desde un enum cuando interactúe con el atributo:

if ($server->status == ServerStatus::Provisioned) {
    $server->status = ServerStatus::Ready;

    $server->save();
}

#Conversión de Arrays de Enums

A veces puede necesitar que su modelo almacene un array de valores enum dentro de una sola columna. Para lograr esto, puede utilizar las conversiones AsEnumArrayObject o AsEnumCollection proporcionadas por Laravel:

use App\Enums\ServerStatus;
use Illuminate\Database\Eloquent\Casts\AsEnumCollection;

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'statuses' => AsEnumCollection::class.':'.ServerStatus::class,
];

#Conversión Encriptada

La conversión encrypted encriptará el valor de un atributo del modelo usando las funciones de encriptación integradas de Laravel. Además, las conversiones encrypted:array, encrypted:collection, encrypted:object, AsEncryptedArrayObject y AsEncryptedCollection funcionan como sus contrapartes no encriptadas; sin embargo, como puede esperar, el valor subyacente se encripta cuando se almacena en su base de datos.

Como la longitud final del texto encriptado no es predecible y es más larga que su equivalente en texto plano, asegúrese de que la columna de base de datos asociada sea de tipo TEXT o mayor. Además, dado que los valores están encriptados en la base de datos, no podrá consultar ni buscar valores de atributos encriptados.

#Rotación de Claves

Como sabrá, Laravel encripta cadenas usando el valor de configuración key especificado en el archivo de configuración app de su aplicación. Normalmente, este valor corresponde al valor de la variable de entorno APP_KEY. Si necesita rotar la clave de encriptación de su aplicación, deberá reencriptar manualmente sus atributos encriptados usando la nueva clave.

#Conversión en Tiempo de Consulta

A veces puede necesitar aplicar conversiones mientras ejecuta una consulta, como cuando selecciona un valor raw de una tabla. Por ejemplo, considere la siguiente consulta:

use App\Models\Post;
use App\Models\User;

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->get();

El atributo last_posted_at en los resultados de esta consulta será una cadena simple. Sería ideal si pudiéramos aplicar una conversión datetime a este atributo al ejecutar la consulta. Afortunadamente, podemos lograr esto usando el método withCasts:

$users = User::select([
    'users.*',
    'last_posted_at' => Post::selectRaw('MAX(created_at)')
            ->whereColumn('user_id', 'users.id')
])->withCasts([
    'last_posted_at' => 'datetime'
])->get();

#Conversores Personalizados

Laravel tiene una variedad de tipos de conversión integrados y útiles; sin embargo, ocasionalmente puede necesitar definir sus propios tipos de conversión. Para crear un conversor, ejecute el comando Artisan make:cast. La nueva clase de conversión se colocará en su directorio app/Casts:

php artisan make:cast Json

Todas las clases de conversión personalizadas implementan la interfaz CastsAttributes. Las clases que implementan esta interfaz deben definir un método get y un método set. El método get es responsable de transformar un valor raw de la base de datos en un valor convertido, mientras que el método set debe transformar un valor convertido en un valor raw que pueda almacenarse en la base de datos. Como ejemplo, reimplementaremos el tipo de conversión integrado json como un tipo de conversión personalizado:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

class Json implements CastsAttributes
{
    /**
     * Convertir el valor dado.
     *
     * @param  array<string, mixed>  $attributes
     * @return array<string, mixed>
     */
    public function get(Model $model, string $key, mixed $value, array $attributes): array
    {
        return json_decode($value, true);
    }

    /**
     * Preparar el valor dado para almacenamiento.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): string
    {
        return json_encode($value);
    }
}

Una vez que haya definido un tipo de conversión personalizado, puede adjuntarlo a un atributo del modelo usando su nombre de clase:

<?php

namespace App\Models;

use App\Casts\Json;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * Los atributos que deben ser convertidos.
     *
     * @var array
     */
    protected $casts = [
        'options' => Json::class,
    ];
}

#Conversión a Objetos de Valor

No está limitado a convertir valores a tipos primitivos. También puede convertir valores a objetos. Definir conversiones personalizadas que conviertan valores a objetos es muy similar a convertir a tipos primitivos; sin embargo, el método set debe retornar un array de pares clave / valor que se usarán para establecer valores raw y almacenables en el modelo.

Como ejemplo, definiremos una clase de conversión personalizada que convierte múltiples valores del modelo en un único objeto de valor Address. Supondremos que el valor Address tiene dos propiedades públicas: lineOne y lineTwo:

<?php

namespace App\Casts;

use App\ValueObjects\Address as AddressValueObject;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use InvalidArgumentException;

class Address implements CastsAttributes
{
    /**
     * Convertir el valor dado.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function get(Model $model, string $key, mixed $value, array $attributes): AddressValueObject
    {
        return new AddressValueObject(
            $attributes['address_line_one'],
            $attributes['address_line_two']
        );
    }

    /**
     * Preparar el valor dado para almacenamiento.
     *
     * @param  array<string, mixed>  $attributes
     * @return array<string, string>
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): array
    {
        if (! $value instanceof AddressValueObject) {
            throw new InvalidArgumentException('El valor dado no es una instancia de Address.');
        }

        return [
            'address_line_one' => $value->lineOne,
            'address_line_two' => $value->lineTwo,
        ];
    }
}

Al convertir a objetos de valor, cualquier cambio realizado en el objeto de valor se sincronizará automáticamente con el modelo antes de que se guarde:

use App\Models\User;

$user = User::find(1);

$user->address->lineOne = 'Valor Actualizado de Dirección';

$user->save();
Примечание

Si planea serializar sus modelos Eloquent que contienen objetos de valor a JSON o arrays, debe implementar las interfaces Illuminate\Contracts\Support\Arrayable y JsonSerializable en el objeto de valor.

#Caché de Objetos de Valor

Cuando se resuelven atributos que se convierten a objetos de valor, Eloquent los almacena en caché. Por lo tanto, se devolverá la misma instancia de objeto si se accede al atributo nuevamente.

Si desea deshabilitar el comportamiento de caché de objetos de las clases de conversión personalizadas, puede declarar una propiedad pública withoutObjectCaching en su clase de conversión personalizada:

class Address implements CastsAttributes
{
    public bool $withoutObjectCaching = true;

    // ...
}

#Serialización Array / JSON

Cuando un modelo Eloquent se convierte a un array o JSON usando los métodos toArray y toJson, sus objetos de valor de conversión personalizada normalmente se serializarán siempre que implementen las interfaces Illuminate\Contracts\Support\Arrayable y JsonSerializable. Sin embargo, cuando usa objetos de valor proporcionados por librerías de terceros, puede que no tenga la capacidad de agregar estas interfaces al objeto.

Por lo tanto, puede especificar que su clase de conversión personalizada será responsable de serializar el objeto de valor. Para ello, su clase de conversión personalizada debe implementar la interfaz Illuminate\Contracts\Database\Eloquent\SerializesCastableAttributes. Esta interfaz indica que su clase debe contener un método serialize que debe devolver la forma serializada de su objeto de valor:

/**
 * Obtener la representación serializada del valor.
 *
 * @param  array<string, mixed>  $attributes
 */
public function serialize(Model $model, string $key, mixed $value, array $attributes): string
{
    return (string) $value;
}

#Conversión Entrante

Ocasionalmente, puede necesitar escribir una clase de conversión personalizada que solo transforme valores que se están estableciendo en el modelo y no realice ninguna operación cuando se recuperan atributos del modelo.

Las conversiones personalizadas solo entrantes deben implementar la interfaz CastsInboundAttributes, que solo requiere que se defina un método set. El comando Artisan make:cast puede invocarse con la opción --inbound para generar una clase de conversión solo entrante:

php artisan make:cast Hash --inbound

Un ejemplo clásico de una conversión solo entrante es una conversión de "hashing". Por ejemplo, podemos definir una conversión que hashea valores entrantes mediante un algoritmo dado:

<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes;
use Illuminate\Database\Eloquent\Model;

class Hash implements CastsInboundAttributes
{
    /**
     * Crear una nueva instancia de la clase de conversión.
     */
    public function __construct(
        protected string|null $algorithm = null,
    ) {}

    /**
     * Preparar el valor dado para almacenamiento.
     *
     * @param  array<string, mixed>  $attributes
     */
    public function set(Model $model, string $key, mixed $value, array $attributes): string
    {
        return is_null($this->algorithm)
                    ? bcrypt($value)
                    : hash($this->algorithm, $value);
    }
}

#Parámetros de Conversión

Al adjuntar una conversión personalizada a un modelo, los parámetros de conversión pueden especificarse separándolos del nombre de la clase usando el carácter : y delimitando múltiples parámetros con comas. Los parámetros se pasarán al constructor de la clase de conversión:

/**
 * Los atributos que deben ser convertidos.
 *
 * @var array
 */
protected $casts = [
    'secret' => Hash::class.':sha256',
];

#Castables

Puede querer permitir que los objetos de valor de su aplicación definan sus propias clases de conversión personalizadas. En lugar de adjuntar la clase de conversión personalizada a su modelo, puede adjuntar alternativamente una clase de objeto de valor que implemente la interfaz Illuminate\Contracts\Database\Eloquent\Castable:

use App\ValueObjects\Address;

protected $casts = [
    'address' => Address::class,
];

Los objetos que implementan la interfaz Castable deben definir un método castUsing que retorne el nombre de la clase del caster personalizado que es responsable de convertir hacia y desde la clase Castable:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Database\Eloquent\Castable;
use App\Casts\Address as AddressCast;

class Address implements Castable
{
    /**
     * Obtener el nombre de la clase caster a usar al convertir hacia / desde este objetivo de conversión.
     *
     * @param  array<string, mixed>  $arguments
     */
    public static function castUsing(array $arguments): string
    {
        return AddressCast::class;
    }
}

Al usar clases Castable, aún puede proporcionar argumentos en la definición $casts. Los argumentos se pasarán al método castUsing:

use App\ValueObjects\Address;

protected $casts = [
    'address' => Address::class.':argument',
];

#Castables y Clases de Conversión Anónimas

Combinando "castables" con las clases anónimas de PHP, puede definir un objeto de valor y su lógica de conversión como un único objeto castable. Para lograr esto, retorne una clase anónima desde el método castUsing de su objeto de valor. La clase anónima debe implementar la interfaz CastsAttributes:

<?php

namespace App\ValueObjects;

use Illuminate\Contracts\Database\Eloquent\Castable;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;

class Address implements Castable
{
    // ...

    /**
     * Obtener la clase caster a usar al convertir hacia / desde este objetivo de conversión.
     *
     * @param  array<string, mixed>  $arguments
     */
    public static function castUsing(array $arguments): CastsAttributes
    {
        return new class implements CastsAttributes
        {
            public function get(Model $model, string $key, mixed $value, array $attributes): Address
            {
                return new Address(
                    $attributes['address_line_one'],
                    $attributes['address_line_two']
                );
            }

            public function set(Model $model, string $key, mixed $value, array $attributes): array
            {
                return [
                    'address_line_one' => $value->lineOne,
                    'address_line_two' => $value->lineTwo,
                ];
            }
        };
    }
}