Installation Add the package via Composer:
composer require neuecommerce/model-casts
Publish the config (if available) with:
php artisan vendor:publish --provider="NeueCommerce\ModelCasts\ServiceProvider"
First Use Case Define a cast in your Eloquent model:
use NeueCommerce\ModelCasts\Casts\JsonArray;
use NeueCommerce\ModelCasts\Casts\Boolean;
class Product extends Model
{
protected $casts = [
'options' => JsonArray::class,
'is_active' => Boolean::class,
];
}
Where to Look First
vendor/neuecommerce/model-casts/src/Casts/ for available cast types.Basic Casting
Use built-in casts like Boolean, JsonArray, or DateTime for common data transformations:
protected $casts = [
'published_at' => \NeueCommerce\ModelCasts\Casts\DateTime::class,
'tags' => \NeueCommerce\ModelCasts\Casts\JsonArray::class,
];
Customizing Casts Extend existing casts for domain-specific logic:
use NeueCommerce\ModelCasts\Casts\JsonArray;
class CustomJsonArray extends JsonArray
{
public function get($model, string $key, $value, array $attributes)
{
return parent::get($model, $key, $array = json_decode($value, true), $attributes);
}
}
Register the custom cast in your model:
protected $casts = [
'metadata' => CustomJsonArray::class,
];
Integration with API Resources Leverage casts to simplify API responses:
public function toArray($request)
{
return [
'id' => $this->id,
'options' => $this->options, // Automatically cast to array
'is_active' => $this->is_active, // Automatically cast to bool
];
}
Mass Assignment
Use casts to sanitize or transform input during create/update:
$product = Product::create([
'options' => '{"size":"large","color":"red"}', // Casts to array
'is_active' => 'yes', // Casts to boolean
]);
Database Storage Optimization
Store complex data as JSON (e.g., tags, metadata) and cast to arrays/objects in PHP:
protected $casts = [
'config' => \NeueCommerce\ModelCasts\Casts\Json::class,
];
Relationships with Casts Cast attributes of related models:
public function user()
{
return $this->belongsTo(User::class)->withDefault([
'is_admin' => false, // Casted via Boolean cast
]);
}
JSON column for JsonArray).null values, malformed JSON, or invalid booleans.Malformed JSON
JsonArray or Json casts may throw exceptions on invalid JSON.json_decode($value, true) with error suppression or a custom cast:
class SafeJsonArray implements CastsAttributes
{
public function get($model, string $key, $value, array $attributes)
{
return json_decode($value, true) ?: [];
}
}
Boolean Cast Ambiguity
"0", "1", "false", or "true" may not cast as expected.Boolean cast or pre-process input:
$isActive = filter_var($request->is_active, FILTER_VALIDATE_BOOLEAN);
Database-Level Constraints
TEXT) may cause issues.JSON or LONGTEXT columns for JSON casts.Circular References in JSON
JsonArray may fail on circular references in nested data.JSON_UNESCAPED_UNICODE or a custom cast with json_encode($value, JSON_THROW_ON_ERROR).Overriding Default Casts
date).custom_date) or use fully qualified namespaces.Performance with Large JSON
$model->setAttribute('options', $value);
\Log::debug('Casted options:', [$model->options]);
$casts. Reorder if dependencies exist.getAttribute: Override getAttribute to debug casting logic:
public function getAttribute($key)
{
\Log::debug("Getting attribute $key", [parent::getAttribute($key)]);
return parent::getAttribute($key);
}
Create Custom Casts
Implement the CastsAttributes interface:
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
class CustomCast implements CastsAttributes
{
public function get($model, string $key, $value, array $attributes)
{
// Decoding logic
}
public function set($model, string $key, $value, array $attributes)
{
// Encoding logic
}
}
Modify Existing Casts
Extend base casts (e.g., Boolean, JsonArray) to add validation or formatting:
class ValidatedJsonArray extends JsonArray
{
public function set($model, string $key, $value, array $attributes)
{
if (!is_array($value)) {
throw new \InvalidArgumentException("Value must be an array.");
}
return parent::set($model, $key, $value, $attributes);
}
}
Global Cast Registration Register casts globally in the service provider:
use Illuminate\Database\Eloquent\Casts\Attribute;
public function boot()
{
Attribute::macro('customCast', function ($cast) {
return new $cast();
});
}
Usage:
protected $casts = [
'data' => Attribute::customCast(CustomCast::class),
];
Conditional Casting Dynamically apply casts based on conditions:
public function getCasts($model)
{
$casts = [
'options' => $model->is_premium ? JsonArray::class : 'array',
];
return $casts;
}
default values in $attributes. Explicitly set defaults in the model:
protected $attributes = [
'is_active' => false,
];
null values gracefully (e.g., return null or a default).toJson()). Test thoroughly.How can I help you explore Laravel packages today?