PHP
Implementing Custom Eloquent Casts for Complex Attributes
Create custom Eloquent casts to handle complex attribute types like value objects, JSON fields, or encrypted data, centralizing transformation logic.
<?php
namespace App\Models\Casts;
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Support\Collection; // Example for a custom type
class JsonCollection implements CastsAttributes
{
/**
* Cast the given value from the database.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param mixed $value
* @param array $attributes
* @return \Illuminate\Support\Collection
*/
public function get($model, $key, $value, $attributes)
{
return new Collection(json_decode($value, true));
}
/**
* Prepare the given value for storage.
*
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param \Illuminate\Support\Collection $value
* @param array $attributes
* @return string
*/
public function set($model, $key, $value, $attributes)
{
return json_encode($value);
}
}
// In your Eloquent Model (e.g., App\Models\Product.php)
/*
<?php
namespace App\Models;
use App\Models\Casts\JsonCollection;
use Illuminate\Database\Eloquent\Model;
class Product extends Model
{
protected $casts = [
'options' => JsonCollection::class,
];
protected $fillable = ['name', 'options'];
}
// Usage example:
// $product = \App\Models\Product::find(1);
// $product->options = collect(['color' => 'red', 'size' => 'L']);
// $product->save();
//
// echo $product->options->get('color'); // Output: red
// $product->options->push(['material' => 'cotton']);
// $product->save();
*/
How it works: Custom Eloquent casts allow you to define how a model attribute is stored in the database and how it's retrieved. By implementing the `CastsAttributes` interface, you create a class with `get()` and `set()` methods that handle the conversion. This is ideal for value objects, complex data structures, or encrypted fields, ensuring consistent data handling across your application without polluting your model with transformation logic. The model then references this custom cast in its `$casts` array.