PHP
Implementing Eloquent Custom Casts
Create custom casts in Laravel Eloquent to define complex serialization and deserialization logic for model attributes, ideal for value objects or non-primitive data types.
// app/Casts/MoneyCast.php
namespace App/Casts;
use Illuminate/Contracts/Database/Eloquent/CastsAttributes;
use Illuminate/Database/Eloquent/Model;
use InvalidArgumentException;
class MoneyCast implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): mixed
{
// Store as integer cents, retrieve as float dollars
return $value / 100;
}
public function set(Model $model, string $key, mixed $value, array $attributes): mixed
{
if (! is_numeric($value)) {
throw new InvalidArgumentException('The given value is not a number.');
}
// Store as integer cents
return (int) ($value * 100);
}
}
// app/Models/Order.php
namespace App/Models;
use App/Casts/MoneyCast;
use Illuminate/Database/Eloquent/Model;
class Order extends Model
{
protected $fillable = ['amount'];
protected $casts = [
'amount' => MoneyCast::class,
];
}
// Usage example:
$order = new Order;
$order->amount = 123.45; // Stored as 12345 in DB
$order->save();
$retrievedOrder = Order::find($order->id);
echo $retrievedOrder->amount; // Output: 123.45 (float)
echo gettype($retrievedOrder->amount); // Output: double
How it works: Custom casts provide a powerful way to define how Eloquent attributes are stored in the database and how they are retrieved as objects or specific types. By implementing the `CastsAttributes` interface, you can control the `get` (retrieval) and `set` (storage) logic. This is extremely useful for handling complex data types, value objects, or non-standard attribute formats, like storing monetary values as cents (integer) but working with them as dollars (float).