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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs