Installation
composer require sofa/eloquence-metable
Register the service provider in config/app.php:
'providers' => [
// ...
Sofa\Eloquence\Metable\MetableServiceProvider::class,
],
Basic Usage
Apply the Metable trait to your Eloquent model:
use Sofa\Eloquence\Metable\Metable;
class Product extends Model
{
use Metable;
}
First Use Case: Storing/Retrieving Metadata
// Set metadata
$product = new Product();
$product->setMeta(['color' => 'red', 'price_range' => 'premium']);
$product->save();
// Retrieve metadata
$metadata = $product->getMeta(); // ['color' => 'red', 'price_range' => 'premium']
$color = $product->getMeta('color'); // 'red'
// Set nested metadata
$product->setMeta(['specs' => ['weight' => '1kg', 'dimensions' => '10x20x30']]);
// Retrieve nested metadata
$weight = $product->getMeta('specs.weight'); // '1kg'
// In a resource
public function toArray($request)
{
return [
'id' => $this->id,
'meta' => $this->getMeta(), // Include metadata in response
];
}
// Set metadata conditionally
if ($product->isPremium()) {
$product->setMeta('price_range', 'premium');
}
// Check metadata existence
if ($product->hasMeta('color')) {
$color = $product->getMeta('color');
}
Product::where('category', 'electronics')->updateMeta([
'stock_status' => 'in_stock',
'last_updated' => now(),
]);
// Override serialization (if needed)
protected function serializeMeta($value)
{
return json_encode($value);
}
protected function deserializeMeta($value)
{
return json_decode($value, true);
}
Database Column Mismatch
meta column (e.g., JSON or TEXT type). Ensure your migration includes:
$table->json('meta')->nullable(); // For Laravel 8+
// OR
$table->text('meta')->nullable();
Nested Metadata Serialization
TEXT instead of JSON, nested arrays may not serialize/deserialize correctly. Prefer JSON for complex structures.Mass Assignment Risks
protected $metaFillable = ['color', 'price_range'];
Performance with Large Metadata
serializeMeta/deserializeMeta methods or database column type.\Log::debug('Raw meta:', [$product->meta]);
JSON column type.Custom Serialization
Override serializeMeta/deserializeMeta for custom formats (e.g., YAML, XML).
Meta Events
Listen for metable.saving/metable.saved events to hook into metadata changes:
event(new MetableSaving($model, $meta));
Query Scopes Add custom scopes for metadata filtering:
public function scopeWithMeta($query, $key, $value)
{
return $query->whereJsonContains('meta->>' . $key, $value);
}
Caching Metadata Cache frequently accessed metadata to reduce database reads:
$meta = Cache::remember("meta_{$product->id}", now()->addHours(1), function () use ($product) {
return $product->getMeta();
});
meta column name via config:
'metable' => [
'column' => 'attributes', // Custom column name
],
protected $autoSaveMeta = false;
How can I help you explore Laravel packages today?