abdylreshit/laravel-eav

A lightweight EAV package for Laravel: add dynamic, typed attributes to any Eloquent model with validation and easy querying.

Installs: 9

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

pkg:composer/abdylreshit/laravel-eav

v0.1.1 2025-10-28 12:17 UTC

This package is auto-updated.

Last update: 2025-10-28 12:39:43 UTC


README

A lightweight, powerful EAV (Entity-Attribute-Value) package for Laravel. Add dynamic, typed attributes to any Eloquent model without modifying your database schema. Perfect for e-commerce platforms, CMS systems, and applications requiring flexible data structures.

Features

Dynamic Attributes - Add unlimited attributes to any model without schema changes
🎯 Type Support - String, text, integer, decimal, boolean, date, datetime, JSON, image, and file types
Validation Ready - Built-in validation support for attribute values
🔍 Easy Querying - Filter models by EAV attributes with fluent API
🌍 Translatable - Support for multi-language attribute names
📦 Zero Configuration - Works out of the box with sensible defaults
🚀 Performance Optimized - Efficient queries with eager loading support

Installation

Install the package via Composer:

composer require abdylreshit/laravel-eav

The package will auto-discover and register its service provider.

Configuration

Publish the migration:

php artisan vendor:publish --provider="Abdylreshit\LaravelEav\Providers\LaravelEavServiceProvider" --tag="migrations"

Run the migration:

php artisan migrate

This creates the necessary tables: attributes and attribute_values.

Quick Start

1. Add the Trait to Your Model

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Abdylreshit\LaravelEav\Traits\HasEavAttributes;

class Product extends Model
{
    use HasEavAttributes;
}

2. Create Attributes

use Abdylreshit\LaravelEav\Models\Attribute;
use Abdylreshit\LaravelEav\Enums\AttributeType;

// Create a color attribute
Attribute::create([
    'name' => 'Color',
    'code' => 'color',
    'type' => AttributeType::STRING,
]);

// Create a price attribute
Attribute::create([
    'name' => 'Price',
    'code' => 'price',
    'type' => AttributeType::DECIMAL,
]);

3. Use Attributes on Your Model

$product = Product::find(1);

// Set a single attribute
$product->setAttribute('color', 'red');

// Set multiple attributes
$product->setAttributes([
    'color' => 'blue',
    'price' => 99.99,
    'in_stock' => true,
]);

// Get an attribute
$color = $product->getAttribute('color'); // 'blue'

// Get multiple attributes
$attrs = $product->getAttributes(['color', 'price']);

// Get all attributes
$allAttrs = $product->getAllAttributes();

// Check if attribute exists
if ($product->hasAttribute('color')) {
    // ...
}

// Delete an attribute
$product->deleteAttribute('color');

Querying with Attributes

Filter models by attribute values:

// Find products with a specific color
$redProducts = Product::whereAttribute('color', 'red')->get();

// Find products by multiple attributes
$products = Product::whereAttributes([
    'color' => 'blue',
    'in_stock' => true,
])->get();

// Combine with other queries
$products = Product::where('category_id', 1)
    ->whereAttribute('price', '>', 50)
    ->get();

Attribute Types

The package supports the following attribute types:

Type Description Column
STRING Short text string_value
TEXT Long text text_value
INTEGER Whole numbers integer_value
DECIMAL Decimal numbers decimal_value
BOOLEAN True/false boolean_value
DATE Date (Y-m-d) date_value
DATETIME DateTime (Y-m-d H:i:s) datetime_value
JSON JSON data json_value
IMAGE Image file image_value
FILE File attachment file_value

Define Attribute Type

use Abdylreshit\LaravelEav\Enums\AttributeType;

Attribute::create([
    'name' => 'Description',
    'code' => 'description',
    'type' => AttributeType::TEXT,
]);

Attribute::create([
    'name' => 'Launch Date',
    'code' => 'launch_date',
    'type' => AttributeType::DATETIME,
]);

Translatable Attributes

Attribute names are translatable out of the box:

$attribute = Attribute::create([
    'name' => ['en' => 'Color', 'fr' => 'Couleur'],
    'code' => 'color',
    'type' => AttributeType::STRING,
]);

// Get the name in a specific language
$nameEn = $attribute->getTranslation('name', 'en'); // 'Color'
$nameFr = $attribute->getTranslation('name', 'fr'); // 'Couleur'

Eager Loading

Eager load EAV values with your model to avoid N+1 queries:

// Eager load all EAV values
$products = Product::with('eavValues.attribute')->get();

foreach ($products as $product) {
    $color = $product->getAttribute('color'); // No additional query
}

Validation

Validate EAV attributes in your request:

use Abdylreshit\LaravelEav\Models\Attribute;

$validated = $request->validate([
    'name' => 'required|string',
    'color' => 'nullable|string|max:50',
    'price' => 'nullable|numeric|min:0',
]);

$product = Product::create($validated);
$product->setAttributes($validated);

Available Methods

Getting Attributes

  • getAttribute(string $code) - Get a single attribute value
  • getAttributes(array $codes) - Get multiple attribute values
  • getAllAttributes() - Get all attributes as an array
  • hasAttribute(string $code) - Check if attribute exists

Setting Attributes

  • setAttribute(string $code, $value) - Set a single attribute
  • setAttributes(array $attributes) - Set multiple attributes

Deleting Attributes

  • deleteAttribute(string $code) - Delete an attribute value

Querying

  • whereAttribute(string $code, $value) - Filter by single attribute
  • whereAttributes(array $attributes) - Filter by multiple attributes

Relationships

  • eavValues() - MorphMany relationship to attribute values

Database Schema

Attributes Table

id - bigInteger, primary key
name - json, translatable attribute name
code - string, unique identifier
type - string, attribute type enum
created_at - timestamp
updated_at - timestamp

Attribute Values Table

id - bigInteger, primary key
attribute_id - bigInteger, foreign key to attributes
model_type - string, polymorphic model type
model_id - bigInteger, polymorphic model id
string_value - string, nullable
text_value - text, nullable
integer_value - integer, nullable
decimal_value - decimal(8,2), nullable
boolean_value - boolean, nullable
date_value - date, nullable
datetime_value - datetime, nullable
json_value - json, nullable
image_value - string, nullable
file_value - string, nullable
created_at - timestamp
updated_at - timestamp

Examples

E-Commerce Product Catalog

// Create attributes for a shoe product
Attribute::create(['name' => 'Size', 'code' => 'size', 'type' => AttributeType::STRING]);
Attribute::create(['name' => 'Color', 'code' => 'color', 'type' => AttributeType::STRING]);
Attribute::create(['name' => 'Material', 'code' => 'material', 'type' => AttributeType::STRING]);

// Set attributes on a product
$shoe = Product::find(1);
$shoe->setAttributes([
    'size' => '42',
    'color' => 'black',
    'material' => 'leather',
]);

// Query products
$blackShoes = Product::whereAttribute('color', 'black')->get();

CMS Page Attributes

// Create attributes for a page
Attribute::create(['name' => 'Author', 'code' => 'author', 'type' => AttributeType::STRING]);
Attribute::create(['name' => 'SEO Title', 'code' => 'seo_title', 'type' => AttributeType::STRING]);
Attribute::create(['name' => 'Published Date', 'code' => 'published_date', 'type' => AttributeType::DATE]);

// Use on your Page model
$page = Page::find(1);
$page->setAttributes([
    'author' => 'John Doe',
    'seo_title' => 'Best Laravel Tips',
    'published_date' => now()->format('Y-m-d'),
]);

Performance Tips

  1. Use Eager Loading - Always eager load EAV values when querying multiple models
  2. Index the code Column - Add a database index to attributes.code for faster queries
  3. Cache Attributes - Cache commonly used attributes
  4. Batch Operations - Use batch setting/getting instead of individual calls

Console Commands

Publish Assets

php artisan eav:publish

Publishes migrations and configuration files.

Migrate EAV Tables

php artisan eav:migrate

Runs EAV-specific migrations.

Troubleshooting

Attribute Not Found

Ensure the attribute exists before setting a value:

$attribute = Attribute::where('code', 'color')->first();
if (!$attribute) {
    Attribute::create([...]);
}

N+1 Query Problem

Use eager loading:

$products = Product::with('eavValues.attribute')->get();

Type Mismatch

Ensure the value type matches the attribute type:

$price = Attribute::where('code', 'price')->first();
// $price->type will be AttributeType::DECIMAL
// Always pass numeric values for decimal attributes

License

The Laravel EAV package is open-sourced software licensed under the MIT license.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Support

For support, please open an issue on the GitHub repository.

Changelog

See CHANGELOG.md for recent changes.

Credits

Created by Abdylreshit

Made with ❤️ for Laravel developers