PHP
Defining Custom Eloquent Attribute Casts
Extend Laravel Eloquent's attribute casting capabilities by creating custom cast classes to handle complex data transformations between your model and database.
<?php
// Step 1: Create a custom cast class
// php artisan make:cast MoneyCast
// In app/Casts/MoneyCast.php
namespace App\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
class MoneyCast implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): mixed
{
// Convert from integer cents to float dollars for retrieval
return $value / 100;
}
public function set(Model $model, string $key, mixed $value, array $attributes): mixed
{
// Convert from float dollars to integer cents for storage
return (int) ($value * 100);
}
}
// Step 2: Use the custom cast in your Eloquent model
// In app/Models/Product.php
namespace App\Models;
use App\Casts\MoneyCast;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $casts = [
'price' => MoneyCast::class,
];
protected $fillable = ['name', 'price'];
}
// Example Usage (e.g., in a controller or route)
// Create a product with a float price
$product = App\Models\Product::create([
'name' => 'Fancy Gadget',
'price' => 19.99, // Stored as 1999 in DB
]);
// Retrieve the product, price is automatically cast back to float
echo $product->price; // Outputs: 19.99
// Update the price
$product->price = 24.50; // Stored as 2450 in DB
$product->save();
echo $product->fresh()->price; // Outputs: 24.5
// Another example: a simple string serialization cast
// In app/Casts/JsonStringCast.php (similar structure to MoneyCast)
class JsonStringCast implements CastsAttributes {
public function get(Model $model, string $key, mixed $value, array $attributes): mixed {
return json_decode($value, true); // Get as array
}
public function set(Model $model, string $key, mixed $value, array $attributes): mixed {
return json_encode($value); // Store as JSON string
}
}
// In model:
// protected $casts = [
// 'options' => JsonStringCast::class,
// ];
How it works: Laravel Eloquent's built-in attribute casting handles common data types, but custom casts provide a powerful way to define complex transformations between your database columns and model attributes. By implementing the `CastsAttributes` interface, you create `get()` and `set()` methods that dictate how an attribute is retrieved from and stored in the database, respectively. This snippet demonstrates a `MoneyCast` that stores currency values as integers (cents) in the database to avoid floating-point inaccuracies, but exposes them as floats (dollars) in the model. Custom casts are ideal for Value Objects, encrypted attributes, or any data requiring specific serialization/deserialization logic.