Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Model Laravel Package

esensi/model

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require esensi/model
    

    Ensure your Laravel project is on version 10.x (compatibility is strict).

  2. 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
    }
    
  3. 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`)
    }
    
  4. Key First Commands:

    • Validation:
      $post = Post::create(['title' => 'Hello', 'content' => 'World']);
      $post->validate(); // Throws ValidationException if invalid
      
    • Encryption:
      $post->password = 'secret123'; // Auto-encrypted in DB
      $post->save();
      
    • Relationships:
      class Post extends Model
      {
          public function author(): BelongsTo
          {
              return $this->belongsTo(User::class);
          }
      }
      

Implementation Patterns

Core Workflows

1. Trait Composition

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;
}
  • Default: All traits are included in the base Model class.
  • Override: Explicitly include/exclude traits for granular control.

2. Validation Integration

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
    }
}
  • Dynamic Rules: Override getValidationRules() for dynamic rules.
  • Custom Messages: Use $messages property for custom error messages.

3. Attribute Handling

Encryption:

protected $encryptable = ['password', 'credit_card'];
  • Automatically encrypts/decrypts fields on save/retrieve.

Type Juggling:

protected $casts = [
    'is_active' => 'boolean',
    'score' => 'integer',
    'metadata' => 'array',
];
  • Uses Laravel’s casting + Esensi’s extensions (e.g., json → array).

4. Relationship Simplification

Auto-Binding:

class Post extends Model
{
    public function author(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}
  • Esensi handles lazy/eager loading with optimized queries.
  • Mass Assignment: Use bindRelationships() to set relationships during create/update.

5. Purging and Soft Deletes

class Post extends Model
{
    use HasSoftDeletes, HasPurgeable;

    protected $purgeable = ['comments']; // Soft-delete related models
}
  • Soft Deletes: $softDeletes = true + deleted_at column.
  • Purge: $post->purge() deletes related models (e.g., comments) before soft-deleting the parent.

6. API Resource Integration

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;
}
  • Returns formatted JSON via toApiResponse() or toArray().

Integration Tips

Laravel Ecosystem

  • Scout: Esensi models integrate with Laravel Scout for search. Add:
    use Esensi\Model\Traits\HasSearchable;
    
  • Notifications: Use notify() with Esensi’s event system:
    $post->notify(new PostPublished($post));
    
  • Events: Dispatch events via dispatch() or fire():
    $post->fire('published', $post);
    

Testing

  • Factories: Extend Esensi’s factory traits:
    use Esensi\Model\Traits\HasFactory;
    
    class PostFactory extends Factory
    {
        use HasFactory;
    }
    
  • Mocking: Use Esensi\Model\Mocks\ModelMock for unit tests:
    $mock = new ModelMock(Post::class);
    $mock->shouldReceive('validate')->once();
    

Performance

  • Query Optimization: Esensi adds select()/with() helpers:
    $posts = Post::select(['id', 'title'])->with('author')->get();
    
  • Caching: Use remember() for cached queries:
    $post = Post::remember(60)->find($id);
    

Gotchas and Tips

Pitfalls

  1. Trait Conflicts:

    • Issue: Mixing Esensi traits with Laravel’s native traits (e.g., HasFactory) may cause method collisions.
    • Fix: Use class_uses() to debug conflicts or override methods:
      public function newFactory(): Factory
      {
          return \Esensi\Model\Factory::new();
      }
      
  2. Encryption Key:

    • Issue: Forgetting to set APP_KEY in .env breaks encryption.
    • Fix: Ensure APP_KEY is 32-character base64-encoded:
      php artisan key:generate
      
  3. Soft Deletes + Purge:

    • Issue: purge() may fail if related models lack softDeletes.
    • Fix: Ensure all purgable models use HasSoftDeletes.
  4. Validation Timing:

    • Issue: validate() runs on save(), but manual calls may bypass hooks.
    • Fix: Use performValidation() for explicit validation before save.
  5. Attribute Juggling:

    • Issue: Custom getAttribute() methods override Esensi’s juggling.
    • Fix: Use getAttributeFromArray() or extend getAttribute() carefully.

Debugging

  1. Log Traits: Enable debug mode in config/esensi.php:

    'debug' => env('ESENSI_DEBUG', false),
    
    • Logs trait method calls to storage/logs/esensi.log.
  2. Query Logging: Add to AppServiceProvider:

    \Esensi\Model\Debugger::enable();
    
  3. Common Errors:

    • Call to undefined method: Missing trait or incorrect method signature.
      • Fix: Check trait source or override the method.
    • Encryption failed: Invalid APP_KEY or missing encryptable fields.
      • Fix: Verify .env and $encryptable array.

Configuration Quirks

  1. Global Config: Override defaults in config/esensi.php:

    'validation' => [
        'throw_exceptions' => true, // Default: false
    ],
    'encryption' => [
        'fields' => ['password', 'api_token'], // Global encryptable fields
    ],
    
  2. Model-Specific Overrides: Use boot() to modify behavior:

    protected static function boot()
    {
        parent::boot();
        static::addGlobalScope(new ActiveScope); // Add a global scope
    }
    
  3. Database Events: Esensi fires events for CRUD operations. Listen via:

    \Esensi\Model\Events\Creating::class => [YourListener::class, 'handle'],
    

Extension Points

  1. Custom Traits: Extend existing traits:
    namespace App\Models\Traits
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route