martes, 2 de septiembre de 2025

Casteo de atributos de modelo en Eloquent

 ¿Es verdad que el Model de Eloquent tiene un array casts? ¿Para qué sirve?

Sí, es verdad. El modelo de Eloquent en Laravel tiene un array llamado $casts, y es una característica muy útil.

¿Qué es y para qué sirve?

El array $casts sirve para convertir automáticamente los atributos de un modelo a un tipo de dato específico cuando se recuperan de la base de datos o se asignan al modelo. Esto te permite trabajar con los datos de una manera más intuitiva y segura en tu código.

Por ejemplo, si tienes una columna en tu base de datos que almacena un valor booleano (como tinyint(1)), Eloquent la tratará por defecto como un entero (0 o 1). Al usar $casts, puedes decirle a Eloquent que la convierta automáticamente a un booleano de PHP (true o false), lo que simplifica tus condicionales.

Aquí tienes una tabla que muestra algunos de los tipos de conversión más comunes que puedes usar:

TipoDescripciónEjemplo
integerConvierte a un entero.'age' => 'integer'
real, float, doubleConvierte a un número de punto flotante.'price' => 'double'
stringConvierte a una cadena de texto.'name' => 'string'
booleanConvierte a un booleano (true o false).'is_published' => 'boolean'
objectDeserializa un JSON en un objeto de PHP.'settings' => 'object'
arrayDeserializa un JSON en un array de PHP.'tags' => 'array'
collectionDeserializa un JSON en una colección de Laravel.'meta' => 'collection'
date, datetime, timestampConvierte a un objeto Carbon.'created_at' => 'datetime'

Ejemplo de uso

Imagina que tienes una tabla de products con columnas is_active (un booleano en la base de datos) y options (un JSON que almacena un array de opciones).

Sin $casts, tu modelo se vería así:

Ejemplo sin Casts
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
}

Con $casts, puedes definir la conversión de la siguiente manera:

Ejemplo con Casts
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'is_active' => 'boolean',
'options' => 'array',
];
}

Con esta configuración, cuando accedas a la propiedad is_active en una instancia del modelo, siempre será un booleano. Del mismo modo, options será automáticamente un array de PHP.

PHP
// Ejemplo en tu código
$product = Product::find(1);

if ($product->is_active) {
    // Esto funciona porque 'is_active' es un booleano
    echo 'El producto está activo.';
}

foreach ($product->options as $option) {
    // Esto funciona porque 'options' es un array de PHP
    echo $option;
}

El uso de `$casts` es una buena práctica porque centraliza la lógica de conversión de tipos en el modelo, lo que hace tu código más limpio y predecible. Esto evita tener que realizar conversiones manuales cada vez que accedes a un atributo, mejorando la legibilidad y reduciendo la probabilidad de errores.

¿También funciona en el sentido inverso? O sea, si a un atributo de un Model que tiene casts boolean le asigno un valor true ¿Se guarda en la base como un 1?

Sí, es completamente cierto.

El array $casts funciona de manera bidireccional. No solo convierte los datos que vienen de la base de datos a un tipo de PHP (como boolean o array), sino que también se encarga de convertir el valor de PHP de vuelta al tipo de dato que la base de datos espera cuando guardas el modelo.

Cuando le asignas true a un atributo que está casteado como boolean, Eloquent lo guarda automáticamente en la base de datos como un 1. Del mismo modo, si le asignas false, se guardará como un 0.


Ejemplo de Conversión Inversa

Aquí tienes un ejemplo práctico que muestra cómo se produce esta conversión de manera transparente.

Ejemplo de Conversión Bidireccional
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
protected $casts = [
'is_active' => 'boolean',
];
}

// En tu código, al guardar el modelo
$product = new Product;
$product->name = 'Camiseta de prueba';

// Le asignamos un booleano de PHP
$product->is_active = true;

// Cuando guardas, Eloquent convierte 'true' a '1' para la base de datos
$product->save();

Cuando esta línea $product->save(); se ejecuta, Eloquent generará una consulta INSERT o UPDATE en la que el valor para la columna is_active será 1, no true.

Este es el principal beneficio de los casts: te permiten trabajar con tipos de datos nativos de PHP en todo tu código sin tener que preocuparte por las conversiones manuales al interactuar con la base de datos.


¿Qué resulta de un atributo que tiene cast boolean cuando el campo en la clave tiene valor nulo?

Esa es una excelente pregunta.

Cuando un atributo tiene el cast boolean y el campo correspondiente en la base de datos tiene un valor NULL, el valor que se obtiene en el modelo de Eloquent es null. No se convierte a true o false.

Esto es un comportamiento intencionado y muy útil. Permite que el atributo tenga tres estados posibles: true (verdadero), false (falso) y null (desconocido o no establecido). Esta flexibilidad es ideal para campos opcionales, como las preferencias de un usuario o un estado que todavía no se ha definido.


Ejemplo Práctico

Imagina que tienes un modelo UserPreference con un campo send_notifications que puede ser 1, 0 o NULL.

Ejemplo de Cast Booleano con Valor Nulo
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class UserPreference extends Model
{
/**
* The attributes that should be cast.
*
* @var array
*/
protected $casts = [
'send_notifications' => 'boolean',
];

/**
* The table associated with the model.
*
* @var string
*/
protected $table = 'user_preferences';
}

// Suponiendo que la tabla `user_preferences` tiene un registro con `id = 1`
// y el valor del campo `send_notifications` es NULL.

$preference = UserPreference::find(1);

// Al acceder al atributo, Eloquent lo convierte a `null`
var_dump($preference->send_notifications);

// Output:
// NULL

Como puedes ver en el ejemplo, el cast boolean de Eloquent maneja los valores 1, 0 y NULL de la siguiente manera:

  • 1 en la base de datos se convierte a true.

  • 0 en la base de datos se convierte a false.

  • NULL en la base de datos se mantiene como null.

Esto te da un control completo sobre el estado de tus datos y te permite usar un solo campo para representar tres posibles escenarios en tu lógica de negocio.

No hay comentarios: