Back
Working with JSON Attributes Using Laravel's Array Casts
Laravel provides AsArrayObject and AsCollection casts to handle complex JSON attributes more effectively, enabling intuitive manipulation of nested data structures.
<?php
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;
class User extends Model
{
protected $casts = [
'settings' => AsArrayObject::class,
'tags' => AsCollection::class
];
}
Let's explore a complete example of a Product model that uses JSON attributes to manage specifications and variants:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Casts\AsArrayObject;
use Illuminate\Database\Eloquent\Casts\AsCollection;
class Product extends Model
{
protected $fillable = ['name', 'specs', 'variants'];
protected $casts = [
'specs' => AsArrayObject::class,
'variants' => AsCollection::class,
];
}
// Migration for this model would look like:
public function up()
{
Schema::create('products', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->json('specs');
$table->json('variants');
$table->timestamps();
});
}
// Usage example:
$product = Product::create([
'name' => 'Gaming Laptop',
'specs' => [
'processor' => 'Intel i7',
'ram' => '16GB',
'storage' => [
'primary' => '512GB SSD',
'secondary' => '1TB HDD'
]
],
'variants' => [
['color' => 'Black', 'price' => 999],
['color' => 'Silver', 'price' => 1099]
]
]);
//
// Update nested specs without any PHP errors
$product->specs['storage']['primary'] = '1TB SSD';
$product->save();
// Use collection methods on variants
$product->variants->push(['color' => 'Red', 'price' => 1199]);
$product->save();
// Filter variants using collection methods
$expensiveVariants = $product->variants->where('price', '>', 1000);
These casts enable seamless manipulation of JSON data while maintaining clean, maintainable code. AsArrayObject provides array-like access, while AsCollection offers Laravel's powerful collection methods.