Installation:
composer require esensi/model
Ensure your Laravel project is on version 10.x (compatibility is strict).
Basic Model Extension:
Replace your default app/Models/Model.php (or create a new one) with:
<?php
namespace App\Models;
use Esensi\Model\Model;
class Model extends \Esensi\Model\Model
{
// Inherits all Esensi traits by default
}
First Use Case:
Create a model (e.g., Post) extending the base:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Post extends Model
{
protected $fillable = ['title', 'content'];
protected $casts = [
'is_published' => 'boolean',
'published_at' => 'datetime',
];
// Auto-handled by Esensi traits:
// - Validation (via `validate()` method)
// - Attribute encryption (e.g., `password`)
// - Soft deletes (if `$softDeletes = true`)
}
Key First Commands:
$post = Post::create(['title' => 'Hello', 'content' => 'World']);
$post->validate(); // Throws ValidationException if invalid
$post->password = 'secret123'; // Auto-encrypted in DB
$post->save();
class Post extends Model
{
public function author(): BelongsTo
{
return $this->belongsTo(User::class);
}
}
Mix and match traits from Esensi\Model to customize behavior:
use Esensi\Model\Traits\{
HasValidation,
HasEncryption,
HasSoftDeletes,
HasPurgeable,
HasAttributeJuggling
};
class Post extends Model
{
use HasValidation, HasEncryption, HasSoftDeletes;
}
Model class.Leverage built-in validation with minimal setup:
class Post extends Model
{
protected $rules = [
'title' => 'required|max:255',
'content' => 'required|min:10',
'email' => 'nullable|email:rfc,dns',
];
public function validate(array $attributes = []): void
{
$this->validateRules($attributes); // Uses $rules
}
}
getValidationRules() for dynamic rules.$messages property for custom error messages.Encryption:
protected $encryptable = ['password', 'credit_card'];
Type Juggling:
protected $casts = [
'is_active' => 'boolean',
'score' => 'integer',
'metadata' => 'array',
];
json → array).Auto-Binding:
class Post extends Model
{
public function author(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
}
bindRelationships() to set relationships during create/update.class Post extends Model
{
use HasSoftDeletes, HasPurgeable;
protected $purgeable = ['comments']; // Soft-delete related models
}
$softDeletes = true + deleted_at column.$post->purge() deletes related models (e.g., comments) before soft-deleting the parent.Pair with Esensi’s esensi/api for automatic serialization:
use Esensi\Model\Concerns\HasApiResource;
class Post extends Model
{
use HasApiResource;
protected $apiResource = \App\Http\Resources\PostResource::class;
}
toApiResponse() or toArray().use Esensi\Model\Traits\HasSearchable;
notify() with Esensi’s event system:
$post->notify(new PostPublished($post));
dispatch() or fire():
$post->fire('published', $post);
use Esensi\Model\Traits\HasFactory;
class PostFactory extends Factory
{
use HasFactory;
}
Esensi\Model\Mocks\ModelMock for unit tests:
$mock = new ModelMock(Post::class);
$mock->shouldReceive('validate')->once();
select()/with() helpers:
$posts = Post::select(['id', 'title'])->with('author')->get();
remember() for cached queries:
$post = Post::remember(60)->find($id);
Trait Conflicts:
HasFactory) may cause method collisions.class_uses() to debug conflicts or override methods:
public function newFactory(): Factory
{
return \Esensi\Model\Factory::new();
}
Encryption Key:
APP_KEY in .env breaks encryption.APP_KEY is 32-character base64-encoded:
php artisan key:generate
Soft Deletes + Purge:
purge() may fail if related models lack softDeletes.HasSoftDeletes.Validation Timing:
validate() runs on save(), but manual calls may bypass hooks.performValidation() for explicit validation before save.Attribute Juggling:
getAttribute() methods override Esensi’s juggling.getAttributeFromArray() or extend getAttribute() carefully.Log Traits:
Enable debug mode in config/esensi.php:
'debug' => env('ESENSI_DEBUG', false),
storage/logs/esensi.log.Query Logging:
Add to AppServiceProvider:
\Esensi\Model\Debugger::enable();
Common Errors:
Call to undefined method: Missing trait or incorrect method signature.
Encryption failed: Invalid APP_KEY or missing encryptable fields.
.env and $encryptable array.Global Config:
Override defaults in config/esensi.php:
'validation' => [
'throw_exceptions' => true, // Default: false
],
'encryption' => [
'fields' => ['password', 'api_token'], // Global encryptable fields
],
Model-Specific Overrides:
Use boot() to modify behavior:
protected static function boot()
{
parent::boot();
static::addGlobalScope(new ActiveScope); // Add a global scope
}
Database Events: Esensi fires events for CRUD operations. Listen via:
\Esensi\Model\Events\Creating::class => [YourListener::class, 'handle'],
namespace App\Models\Traits
How can I help you explore Laravel packages today?