zairakai / laravel-eloquent
Enhanced Eloquent model trait for automatic table management, primary key detection, and JSON serialization with column mapping
Installs: 0
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Forks: 0
pkg:composer/zairakai/laravel-eloquent
Requires
- php: ^8.3
- illuminate/database: ^11.0 || ^12.0
- illuminate/support: ^11.0 || ^12.0
- laravel/framework: ^11.0 || ^12.0
Requires (Dev)
- driftingly/rector-laravel: ^2.1
- ergebnis/composer-normalize: ^2.49
- larastan/larastan: ^3.9
- laravel/pint: ^1.27
- nunomaduro/phpinsights: ^2.13
- orchestra/testbench: ^9.0 || ^10.0
- phpmetrics/phpmetrics: ^2.9
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^10.0 || ^11.0
- rector/rector: ^2.3
- zairakai/laravel-dev-tools: ^3.0
Suggests
- ergebnis/composer-normalize: Automated composer.json normalization
README
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
| Stub | Description |
|---|---|
model.stub | Standard model extending BaseModel |
model.pivot.stub | Pivot model extending BasePivot |
model.plain.stub | Model 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
| Method | Description |
|---|---|
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
| Constant | Type | Description |
|---|---|---|
TABLE_NAME | string | Override automatic table name |
PRIMARY_KEY | string | Override primary key name |
COLUMNS | array<string, string> | Application key → DB column mapping |
COLUMNS_DELETED | array<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:
| Class | Table |
|---|---|
App\Models\User | users |
App\Models\Contact\Email | contact_emails |
App\Models\Product | products |