zairakai/laravel-eloquent

Enhanced Eloquent model trait for automatic table management, primary key detection, and JSON serialization with column mapping

Fund package maintenance!
Patreon
Other

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Forks: 0

pkg:composer/zairakai/laravel-eloquent

v3.1.1 2026-02-23 16:24 UTC

This package is auto-updated.

Last update: 2026-02-23 15:31:15 UTC


README

Main Develop Security Coverage

GitLab Release Packagist Downloads

License

PHP Laravel Static Analysis Code Style

Enhanced Eloquent model classes and traits for automatic table management, primary key detection, JSON serialization with column mapping, and column resolution with migration support in Laravel applications.

Lightweight utility package Provides abstract classes (BaseModel, BasePivot) and trait (BaseTable) that eliminate boilerplate code when working with Eloquent models, especially for projects with custom database column naming conventions.

Installation

composer require zairakai/laravel-eloquent

Optional: Publish configuration and stubs:

php artisan vendor:publish --tag=laravel-eloquent          # Everything
php artisan vendor:publish --tag=laravel-eloquent-config   # Config only
php artisan vendor:publish --tag=laravel-eloquent-stubs    # Stubs only

Quick Start

Extend BaseModel (Recommended)

use Zairakai\LaravelEloquent\Models\BaseModel;

class User extends BaseModel
{
    public const COLUMNS = [
        'id'    => 'user_id',
        'email' => 'user_email',
        'name'  => 'full_name',
    ];

    protected $fillable = ['user_email', 'full_name'];
}

Use BaseTable Trait

use Illuminate\Database\Eloquent\Model;
use Zairakai\LaravelEloquent\Traits\BaseTable;

class User extends Model
{
    use BaseTable;

    public const COLUMNS = [
        'id'    => 'user_id',
        'email' => 'user_email',
    ];
}

For Pivot Tables

use Zairakai\LaravelEloquent\Models\BasePivot;

class RoleUser extends BasePivot
{
    public const TABLE_NAME = 'role_user';

    public const COLUMNS = [
        'roleId' => 'role_id',
        'userId' => 'user_id',
    ];
}

Column Resolution

Active Columns (COLUMNS)

Maps application keys to database column names. All trait methods (getAttribute, setAttribute, fill, isFillable) transparently use this mapping:

class User extends BaseModel
{
    public const COLUMNS = [
        'id'    => 'user_id',    // getPrimaryKeyName() returns 'user_id'
        'email' => 'user_email',
    ];
}

$user->fill(['email' => 'foo@bar.com']); // writes to 'user_email'
$user->email;                            // reads from 'user_email'
json_encode($user);                      // {"id": 1, "email": "foo@bar.com"}

Deprecated Columns (COLUMNS_DELETED)

Redirects old keys to new ones with logging (warns during migration, no hard breakage):

class User extends BaseModel
{
    public const COLUMNS = [
        'email' => 'user_email',
    ];

    public const COLUMNS_DELETED = [
        'mail'     => 'email',   // 'mail' → 'email' → 'user_email'
        'username' => 'email',   // same
    ];
}

$user->mail; // Works, logs a deprecation warning

Chains are followed automatically: veryOld → old → new → db_column.

Configuration

Publish the configuration file to customise logging behaviour:

php artisan vendor:publish --tag=laravel-eloquent-config

Key options in config/laravel-eloquent.php:

'logging' => [
    'enabled'           => env('ELOQUENT_LOGGING_ENABLED', true),
    'channel'           => env('ELOQUENT_LOGGING_CHANNEL'),   // null = default channel
    'include_backtrace' => env('ELOQUENT_LOGGING_BACKTRACE', true),
    'backtrace_depth'   => env('ELOQUENT_LOGGING_BACKTRACE_DEPTH', 5),
    'levels' => [
        'deprecated' => env('ELOQUENT_LOG_LEVEL_DEPRECATED', 'warning'),
        'missing'    => env('ELOQUENT_LOG_LEVEL_MISSING', 'info'),
    ],
    'excluded_models' => [
        // App\Models\LegacyUser::class,
    ],
],

Set ELOQUENT_LOGGING_ENABLED=false in production to disable all column-resolution logging.

Custom Stubs

After publishing stubs, php artisan make:model uses BaseModel automatically:

php artisan vendor:publish --tag=laravel-eloquent-stubs
php artisan make:model Product
StubDescription
model.stubStandard model extending BaseModel
model.pivot.stubPivot model extending BasePivot
model.plain.stubModel with BaseTable trait only

Model Conversion

Convert existing models to use BaseModel/BasePivot:

php artisan eloquent:convert --dry-run              # Preview changes
php artisan eloquent:convert                        # Convert app/Models
php artisan eloquent:convert --path=app/Models/Legacy
php artisan eloquent:convert --force                # No confirmation

API Reference

Methods

MethodDescription
getTableName()Get the resolved table name (from TABLE_NAME or class name)
getPrimaryKeyName()Get the resolved primary key (from PRIMARY_KEY or COLUMNS['id'])
resolveColumn(string $key)Static: resolve application key to DB column
getColumn(string $key)Instance: resolve application key to DB column
fill(array $attributes)Fill model using mapped keys
getAttribute(mixed $key)Get attribute via mapped key
setAttribute(mixed $key, mixed $value)Set attribute via mapped key
isFillable(mixed $key)Check fillability using mapped key
toReadableArray()Convert to array with application keys (reverse mapping)
toJson($options)JSON with application keys
initializeBaseTable()Boot trait (called automatically by Eloquent)

Constants

ConstantTypeDescription
TABLE_NAMEstringOverride automatic table name
PRIMARY_KEYstringOverride primary key name
COLUMNSarray<string, string>Application key → DB column mapping
COLUMNS_DELETEDarray<string, string>Deprecated key redirects (logged as warnings)

Automatic Table Name Resolution

When TABLE_NAME is not defined, the table name is derived from the class name:

ClassTable
App\Models\Userusers
App\Models\Contact\Emailcontact_emails
App\Models\Productproducts

Contributing

Code Of Conduct Contributing

Getting Help

License Security Policy Issues Discord