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(2mo ago)15971.0k↑18.8%8[2 issues](https://github.com/f9webltd/laravel-deletable/issues)1MITPHPPHP ^8.2CI passing

Since Jul 10Pushed 2mo 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 1mo ago

READMEChangelog (10)Dependencies (6)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

60

—

FairBetter than 99% of packages

Maintenance85

Actively maintained with recent releases

Popularity47

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity75

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

72d 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

[silber/bouncer

Eloquent roles and abilities.

3.6k4.4M25](/packages/silber-bouncer)[mongodb/laravel-mongodb

A MongoDB based Eloquent model and Query builder for Laravel

7.1k7.2M71](/packages/mongodb-laravel-mongodb)[cviebrock/eloquent-sluggable

Easy creation of slugs for your Eloquent models in Laravel

4.0k13.6M253](/packages/cviebrock-eloquent-sluggable)[dyrynda/laravel-model-uuid

This package allows you to easily work with UUIDs in your Laravel models.

4802.8M8](/packages/dyrynda-laravel-model-uuid)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[watson/validating

Eloquent model validating trait.

9723.3M47](/packages/watson-validating)

PHPackages © 2026

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