PHPackages                             f9webltd/laravel-deletable - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. f9webltd/laravel-deletable

ActiveLibrary[Database &amp; ORM](/categories/database)

f9webltd/laravel-deletable
==========================

Gracefully restrict deletion of Laravel Eloquent models

3.0.0(3mo ago)15875.5k↓51.5%8[2 issues](https://github.com/f9webltd/laravel-deletable/issues)1MITPHPPHP ^8.2CI passing

Since Jul 10Pushed 3mo ago1 watchersCompare

[ Source](https://github.com/f9webltd/laravel-deletable)[ Packagist](https://packagist.org/packages/f9webltd/laravel-deletable)[ Docs](https://github.com/f9webltd/laravel-deletable)[ RSS](/packages/f9webltd-laravel-deletable/feed)WikiDiscussions master Synced 2d ago

READMEChangelog (10)Dependencies (12)Versions (16)Used By (1)

[![](https://camo.githubusercontent.com/5bc5e3691b06e468e783d703d706d40a132158c96444b348f8e272ce643bd6b8/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f4c61726176656c25323044656c657461626c652e706e673f7468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d66397765626c74642532466c61726176656c2d64656c657461626c65267061747465726e3d617263686974656374267374796c653d7374796c655f31266465736372697074696f6e3d477261636566756c6c792b72657374726963742b64656c6574696f6e2b6f662b4c61726176656c2b456c6f7175656e742b6d6f64656c73266d643d312673686f7757617465726d61726b3d3026666f6e7453697a653d313030707826696d616765733d7472617368)](https://camo.githubusercontent.com/5bc5e3691b06e468e783d703d706d40a132158c96444b348f8e272ce643bd6b8/68747470733a2f2f62616e6e6572732e6265796f6e64636f2e64652f4c61726176656c25323044656c657461626c652e706e673f7468656d653d6c69676874267061636b6167654d616e616765723d636f6d706f7365722b72657175697265267061636b6167654e616d653d66397765626c74642532466c61726176656c2d64656c657461626c65267061747465726e3d617263686974656374267374796c653d7374796c655f31266465736372697074696f6e3d477261636566756c6c792b72657374726963742b64656c6574696f6e2b6f662b4c61726176656c2b456c6f7175656e742b6d6f64656c73266d643d312673686f7757617465726d61726b3d3026666f6e7453697a653d313030707826696d616765733d7472617368)

![PHP ^8.2](https://camo.githubusercontent.com/fa17bda6467c1bb0eb1e951a14530c78330a9fb1cfa87b1918c1e33522fdb812/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d253545382e322d627269676874677265656e)[![Packagist Version](https://camo.githubusercontent.com/6dcd559287e22c38b263c62c2375be272fdc566744142a6e4f3a0fe4046e7526/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f66397765626c74642f6c61726176656c2d64656c657461626c653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/f9webltd/laravel-deletable)[![Total Downloads](https://camo.githubusercontent.com/e2af98ec3c87cad0c05a43810e1c907ca8eb79d417251ccb76e2c15b67b2fc8f/68747470733a2f2f706f7365722e707567782e6f72672f66397765626c74642f6c61726176656c2d64656c657461626c652f646f776e6c6f6164732e706e67)](https://packagist.org/packages/f9webltd/laravel-deletable)[![run-tests](https://github.com/f9webltd/laravel-deletable/actions/workflows/run-tests.yml/badge.svg)](https://github.com/f9webltd/laravel-deletable/actions/workflows/run-tests.yml)[![StyleCI Status](https://camo.githubusercontent.com/b6bf9e30f2ffee82d7e1e0c640da818dc34b72844fd3e7b1876a7c6cb741a241/68747470733a2f2f6769746875622e7374796c6563692e696f2f7265706f732f3237383538313331382f736869656c64)](https://github.styleci.io/repos/278581318)[![Packagist License](https://camo.githubusercontent.com/0253228519b3f857c4c7ba32904964b6c357f55cf2304c806cca151d4d033fc6/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f6c2f66397765626c74642f6c61726176656c2d64656c657461626c653f7374796c653d666c61742d737175617265)](https://packagist.org/packages/f9webltd/laravel-deletable)

Laravel Deletable
=================

[](#laravel-deletable)

Gracefully handle deletion restrictions on your [Eloquent models](https://laravel.com/docs/master/eloquent), as featured on [Laravel News](https://laravel-news.com/laravel-deletable-trait)

Requirements
------------

[](#requirements)

- PHP `^8.2`
- Laravel `^11.0` / `^12.0` / `^13.0`

The package supports actively supported Laravel releases as per the official [Laravel Support Policy](https://laravel.com/docs/master/releases#support-policy).

For legacy support (older Laravel and PHP versions) use [1.0.6](https://github.com/f9webltd/laravel-deletable/tree/1.0.6) or [2.1.0](https://github.com/f9webltd/laravel-deletable/tree/2.1.0).

Installation
------------

[](#installation)

```
composer require f9webltd/laravel-deletable
```

The package will automatically register itself.

Optionally publish the configuration file by running: `php artisan vendor:publish` and selecting the appropriate package.

Documentation
-------------

[](#documentation)

### Usage

[](#usage)

Within an Eloquent model use the `RestrictsDeletion` trait:

```
namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
   use RestrictsDeletion;
}
```

The trait overrides calls to Eloquent's `delete()` method.

Implement the `isDeletable()` method within the model in question.

This method should return `true` to allow deletion and `false` to deny deletion:

```
namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;

class User extends Model
{
  use RestrictsDeletion;

  public function isDeletable() : bool
  {
    return $this->orders()->doesntExist();
  }
}
```

The above denies deletion of users with orders.

None deletable models throw an exception when the `isDeletable()` method returns `false`:

```
namespace App\Controllers;

use F9Web\LaravelDeletable\Exceptions\NoneDeletableModel;
use App\User;

class UsersController
{
  public function destroy(User $user) : bool
  {
    try {
      $user->delete();
    } catch (NoneDeletableModel $e) {
      // dd($ex->getMessage());
    }
  }
}
```

#### Eloquent Base Model

[](#eloquent-base-model)

As the default `isDeletable()` method returns `true`, a base Eloquent model can be optionally defined from which all models extend. Each model can then optionally implement the `isDeletable()` method as needed.

### Customising Messages

[](#customising-messages)

The default exception message is defined within the config `f9web-laravel-deletable.messages.default` and is simply `The model cannot be deleted`.

By setting `f9web-laravel-deletable.messages.default` to `null` a more detailed message is automatically generated i.e. `Restricted deletion: App\User - 1 is not deletable`.

Custom messages can be set within the `isDeletable()` method:

```
namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
  use RestrictsDeletion;

  public function isDeletable() : bool
  {
    if (Str::endsWith($this->email, 'f9web.co.uk')) {
        return $this->denyDeletionReason('Users with f9web.co.uk company email addresses cannot be deleted');
    }

    return true;
  }
}
```

The `denyDeletionReason()` method can be used to specify the exception message.

In the above case, the exception message is `Users with f9web.co.uk company email addresses cannot be deleted`.

### Multiple Checks

[](#multiple-checks)

Multiple checks can be performed within `isDeletable()` if necessary, each of which returning a different exception message:

```
namespace App;

use F9Web\LaravelDeletable\Traits\RestrictsDeletion;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
  use RestrictsDeletion;

  public function isDeletable() : bool
  {
    if (Str::endsWith($this->email, 'f9web.co.uk')) {
       return $this->denyDeletionReason('Users with f9web.co.uk company email addresses cannot be deleted');
    }

    if ($this->orders->isNotEmpty()) {
       return false;
    }

    if ($this->purchaseOrders->isNotEmpty()) {
       return $this->denyDeletionReason('This user has active purchase orders and cannot be deleted');
    }

    if ($this->overdueInvoices->isNotEmpty()) {
       return $this->denyDeletionReason('Users with overdue invoices cannot be deleted');
    }

    return true;
  }
}
```

Contribution
------------

[](#contribution)

Any ideas are welcome. Feel free to submit any issues or pull requests.

Testing
-------

[](#testing)

```
composer test
```

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Rob Allport](https://github.com/ultrono) for [F9 Web Ltd.](https://www.f9web.co.uk)
- [All Contributors](https://github.com/f9webltd/laravel-deletable/graphs/contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

59

—

FairBetter than 98% of packages

Maintenance78

Regular maintenance activity

Popularity46

Moderate usage in the ecosystem

Community18

Small or concentrated contributor base

Maturity76

Established project with proven stability

 Bus Factor1

Top contributor holds 77.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~172 days

Recently: every ~182 days

Total

13

Last Release

117d ago

Major Versions

1.0.6 → 2.0.02024-03-10

2.1.0 → 3.0.02026-03-08

PHP version history (3 changes)1.0.0PHP ^7.2

1.0.3PHP ^7.2 | ^8.0

2.0.0PHP ^8.2

### Community

Maintainers

![](https://www.gravatar.com/avatar/a91beab733af9a538e27dce750a4dbc1a3738d914b39dbb1f7c71475ff380109?d=identicon)[ultrono](/maintainers/ultrono)

---

Top Contributors

[![ultrono](https://avatars.githubusercontent.com/u/1782734?v=4)](https://github.com/ultrono "ultrono (14 commits)")[![laravel-shift](https://avatars.githubusercontent.com/u/15991828?v=4)](https://github.com/laravel-shift "laravel-shift (3 commits)")[![sald19](https://avatars.githubusercontent.com/u/1674971?v=4)](https://github.com/sald19 "sald19 (1 commits)")

---

Tags

eloquenteloquent-modelseloquent-ormlaravellaravel-deletelaravel-packagelaravel-softdeletelaravel-softdeletes-traitlaraveleloquentlaravel-eloquentsoft deleteslaravel deletelaravel destroy model

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/f9webltd-laravel-deletable/health.svg)

```
[![Health](https://phpackages.com/badges/f9webltd-laravel-deletable/health.svg)](https://phpackages.com/packages/f9webltd-laravel-deletable)
```

###  Alternatives

[psalm/plugin-laravel

Psalm plugin for Laravel

3355.3M345](/packages/psalm-plugin-laravel)[api-platform/laravel

API Platform support for Laravel

58171.5k14](/packages/api-platform-laravel)[spatie/laravel-permission

Permission handling for Laravel 12 and up

12.9k102.4M1.4k](/packages/spatie-laravel-permission)[laravel/ai

The official AI SDK for Laravel.

1.0k3.2M194](/packages/laravel-ai)[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9762.4M131](/packages/roots-acorn)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k8.4M96](/packages/mongodb-laravel-mongodb)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
