Installation
composer require rinvex/laravel-attributes
Publish the migration and config:
php artisan vendor:publish --provider="Rinvex\Attributes\AttributesServiceProvider"
php artisan migrate
Define an Attribute Group
In your model (e.g., User.php), declare attributes:
use Rinvex\Attributes\Traits\HasAttributes;
class User extends Model
{
use HasAttributes;
protected $attributes = [
'personal' => [
'name' => 'string',
'age' => 'integer',
],
'contact' => [
'email' => 'string',
'phone' => 'string',
],
];
First Use Case: Set/Get Attributes
$user = new User();
$user->setAttribute('personal.name', 'John Doe'); // Set
$user->getAttribute('personal.name'); // Get
Dynamic Attribute Management
Use setAttribute() and getAttribute() for runtime flexibility:
$user->setAttribute('contact.email', 'john@example.com');
$user->getAttribute('contact.email');
Validation
Leverage Laravel’s validation rules via validateAttribute():
$user->validateAttribute('contact.email', 'required|email');
Querying Attributes
Use whereAttribute() for EAV queries:
User::whereAttribute('personal.age', '>', 25)->get();
Attribute Groups as Relations Access groups like relations:
$user->personal; // Returns a collection of attributes
$user->contact->phone; // Dot notation
Mass Assignment
Use fillAttributes() for bulk updates:
$user->fillAttributes([
'personal.name' => 'Jane Doe',
'personal.age' => 30,
]);
$user->cacheAttributes(['personal', 'contact']);
attributes.storing and attributes.retrieved:
event(new \Rinvex\Attributes\Events\AttributeStored($user, 'personal.name'));
toArray() or toJson():
$user->toArray(); // Includes attributes
Migration Conflicts
attributes table schema to match the package’s expectations (e.g., entity_type, group, name, value columns).Caching Quirks
$user->forgetAttribute('personal.name');
$user->forgetAttributes(['personal', 'contact']);
Case Sensitivity
group.name) are case-sensitive. Use consistent casing (e.g., snake_case).Mass Assignment Risks
fillAttributes() to avoid injection:
$user->fillAttributes($request->only(['personal.*']));
Performance with Large Datasets
whereAttribute() on non-indexed columns. Add indexes to group and name in the attributes table:
Schema::table('attributes', function (Blueprint $table) {
$table->index(['entity_type', 'group', 'name']);
});
dd($user->attributes) to inspect raw EAV data.whereAttribute():
\DB::enableQueryLog();
User::whereAttribute('personal.age', '>', 25)->get();
\DB::getQueryLog();
Custom Attribute Types
Extend Rinvex\Attributes\Contracts\Attribute for custom logic (e.g., encrypted values):
class EncryptedAttribute implements Attribute
{
public function get($model, $value)
{
return decrypt($value);
}
}
Override Default Behavior Replace the trait in your model:
use Rinvex\Attributes\Traits\HasAttributes as BaseHasAttributes;
class User extends Model
{
use BaseHasAttributes {
BaseHasAttributes::getAttribute as private getAttributeBase;
}
public function getAttribute($name)
{
// Custom logic
return $this->getAttributeBase($name);
}
}
Add Global Scopes Attach scopes to filter attributes globally:
use Rinvex\Attributes\Scopes\AttributeScope;
class User extends Model
{
protected static function booted()
{
static::addGlobalScope(new AttributeScope(['personal.age >', 25]));
}
}
How can I help you explore Laravel packages today?