Weave Code
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

Laravel Deletable Laravel Package

f9webltd/laravel-deletable

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require f9webltd/laravel-deletable
    

    Publish the config (optional):

    php artisan vendor:publish --provider="F9\Deletable\DeletableServiceProvider" --tag="config"
    
  2. First Use Case: Apply the Deletable trait to an Eloquent model:

    use F9\Deletable\Traits\Deletable;
    
    class User extends Model
    {
        use Deletable;
    }
    

    Now, User::destroy() will soft-delete by default (if using SoftDeletes trait) or throw an exception if deletion is restricted.


Where to Look First

  • Config: config/deletable.php (defines default behavior, e.g., throw_exception_on_delete).
  • Model Trait: F9\Deletable\Traits\Deletable (core logic).
  • Exceptions: F9\Deletable\Exceptions\DeletableException (custom exceptions for blocked deletions).

Implementation Patterns

Core Workflow

  1. Soft Deletes + Deletable: Combine with Laravel’s SoftDeletes for soft deletion:

    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class User extends Model
    {
        use Deletable, SoftDeletes;
        protected $dates = ['deleted_at'];
    }
    
    • Deletion attempts trigger soft deletion unless restricted.
  2. Hard Deletes with Restrictions: Override isDeletable() to enforce rules:

    public function isDeletable(): bool
    {
        return $this->role === 'admin' || $this->isActive();
    }
    
  3. Custom Logic: Extend the trait or use events (deleting, deleted) to add pre/post logic:

    protected static function booted()
    {
        static::deleting(function ($model) {
            // Log deletion attempts
            Log::info("Deleting {$model->class} ID: {$model->id}");
        });
    }
    

Integration Tips

  • API Controllers: Wrap deletion in a try-catch to return user-friendly messages:

    try {
        $user->delete();
    } catch (DeletableException $e) {
        return response()->json(['error' => $e->getMessage()], 403);
    }
    
  • Admin Panels: Use the isDeletable() method to disable delete buttons conditionally:

    <button disabled="{{ !$user->isDeletable() }}">
        Delete
    </button>
    
  • Seeding: Bypass restrictions during seeding by setting config(['deletable.throw_exception_on_delete' => false]).


Gotchas and Tips

Pitfalls

  1. Soft Deletes Conflict: If using SoftDeletes, ensure deleted_at is in $dates. Otherwise, the trait silently fails.

  2. Circular Dependencies: Avoid calling delete() recursively (e.g., in model observers or events). Use forceDelete() explicitly if needed.

  3. Mass Deletion: Model::destroy([1, 2, 3]) checks each model individually. For bulk operations, use:

    $models->each(fn ($model) => $model->delete());
    

Debugging

  • Check Restrictions: Log isDeletable() results to debug why deletion fails:

    dd($model->isDeletable()); // Debug in Tinker or logs
    
  • Exception Handling: Override getDeletableException() for custom messages:

    protected function getDeletableException(): DeletableException
    {
        return new DeletableException("Cannot delete inactive users.");
    }
    

Extension Points

  1. Custom Rules: Create a reusable rule class:

    class CanDeleteIfActive implements ShouldBeDeletable
    {
        public function isDeletable(Model $model): bool
        {
            return $model->isActive();
        }
    }
    

    Then use it in isDeletable():

    public function isDeletable(): bool
    {
        return (new CanDeleteIfActive())->isDeletable($this);
    }
    
  2. Global Overrides: Modify the config to change default behavior (e.g., throw_exception_on_deletefalse for silent failures).

  3. Event Listeners: Listen for deleting events to add dynamic restrictions:

    event(new Deleting($model));
    // Check external API or DB state here
    
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.
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle