spatie/laravel-schemaless-attributes
Add “schemaless” JSON attributes to Laravel Eloquent models. Store arbitrary key/value data in one JSON column with a fluent API: get/set via properties or arrays, dot-notation access, defaults, forget keys, and query scopes for matching attributes.
Begin by installing the package via Composer:
composer require spatie/laravel-schemaless-attributes
Next, create a migration to add a JSON column to your model’s table using the schemalessAttributes macro:
Schema::table('products', function (Blueprint $table) {
$table->schemalessAttributes('meta');
});
Then, in your Eloquent model, add the cast and a custom scope:
use Spatie\SchemalessAttributes\Casts\SchemalessAttributes;
class Product extends Model
{
public $casts = [
'meta' => SchemalessAttributes::class,
];
public function scopeWithMeta(): Builder
{
return $this->meta->modelScope();
}
}
You can now start using schemaless attributes immediately:
$product->meta->brand = 'Acme';
$product->save();
dark_mode, notifications) per user.branding, feature_flags) in a config JSON column.$product->meta->set('specs.color', 'navy');
$value = $product->meta->get('specs.color');
$product->meta = ['color' => 'red', 'size' => 'L'];
// or
$product->meta->set(['color' => 'blue', 'stock' => 100]);
Product::withMeta('color', 'red')->get();
Product::withMeta('specs.weight', '>', 5)->get();
Product::withMeta(['category' => 'tools', 'brand' => 'DeWalt'])->get();
HasSchemalessAttributes trait to avoid repetition.$product->meta['specs']['color'] = 'blue') won’t persist unless you assign the entire meta or call set(). Use dot notation ($product->meta->set('specs.color', 'blue')) or assign an array to trigger changes.JsonException.-> operator: Use meta->color in scopes (not meta.color) when querying nested keys:
Product::withMeta('specs->weight', '>', 5)->get();
unset() vs forget(): Use unset($product->meta['key']) (works via ArrayAccess) or $product->meta->forget('key')—but not both, as mixing may cause unexpected behavior. Always call save() after modifications.ALTER TABLE products ADD INDEX (meta->'$.color')), though this package doesn’t auto-generate them.SchemalessAttributesTrait: For models with >1 schemaless column (e.g., meta, settings), use the SchemalessAttributesTrait and declare them in $schemalessAttributes.$product->meta->all() or json_encode($product->meta) to inspect current values before saving.How can I help you explore Laravel packages today?