Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/spatie/laravel-deleted-models
Automatically copy deleted records to a separate table
https://github.com/spatie/laravel-deleted-models
deletion eloquent laravel php
Last synced: 4 days ago
JSON representation
Automatically copy deleted records to a separate table
- Host: GitHub
- URL: https://github.com/spatie/laravel-deleted-models
- Owner: spatie
- License: mit
- Created: 2023-01-12T07:41:48.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2025-01-09T11:25:03.000Z (14 days ago)
- Last Synced: 2025-01-12T11:07:00.267Z (11 days ago)
- Topics: deletion, eloquent, laravel, php
- Language: PHP
- Homepage: https://freek.dev/2416-a-package-to-automatically-copy-deleted-records-to-a-separate-table
- Size: 124 KB
- Stars: 362
- Watchers: 5
- Forks: 23
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE.md
Awesome Lists containing this project
README
# Automatically copy deleted records to a separate table
[![Latest Version on Packagist](https://img.shields.io/packagist/v/spatie/laravel-deleted-models.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-deleted-models)
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-deleted-models/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/spatie/laravel-deleted-models/actions?query=workflow%3Arun-tests+branch%3Amain)
[![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/spatie/laravel-deleted-models/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/spatie/laravel-deleted-models/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain)
[![Total Downloads](https://img.shields.io/packagist/dt/spatie/laravel-deleted-models.svg?style=flat-square)](https://packagist.org/packages/spatie/laravel-deleted-models)When deleting an Eloquent model, this package will copy the attributes of that model to a new table called `deleted_models`. You can view this as a sort of "Recycle bin for models".
```php
$blogPost = BlogPost::find(5); // an Eloquent model$blogPost->delete(); // values will be copied to the `deleted_models` table.
```To restore a previous model you can call `restore` and pass the id.
```php
$blogPost = BlogPost::restore(5); // $blogPost will be restored and returned
```This way of preserving information when deleting can be seen as an alternative to soft deletes. You can read more on the trade-offs [in this blog post](https://freek.dev/2416-a-package-to-automatically-copy-deleted-records-to-a-separate-table).
## Support us
[](https://spatie.be/github-ad-click/laravel-deleted-models)
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards).
## Installation
You can install the package via composer:
```bash
composer require spatie/laravel-deleted-models
```To create the `deleted_models` table, you can publish and run the migrations with:
```bash
php artisan vendor:publish --tag="deleted-models-migrations"
php artisan migrate
```Optionally, you can publish the config file with:
```bash
php artisan vendor:publish --tag="deleted-models-config"
```This is the contents of the published config file:
```php
return [
/*
* The model uses to store deleted models.
*/
'model' => Spatie\DeletedModels\Models\DeletedModel::class,/*
* After this amount of days, the records in `deleted_models` will be deleted
*
* This functionality uses Laravel's native pruning feature.
*/
'prune_after_days' => 365,
];
```The pruning of the `deleted_models` table depends on Laravel's native pruning feature. Don't forget to schedule the `model:prune` as instructed [in Laravel's docs](https://laravel.com/docs/9.x/eloquent#pruning-models).
```php
$schedule->command('model:prune', [
'--model' => [\Spatie\DeletedModels\Models\DeletedModel::class],
])->daily();
```## Usage
You should add the `KeepsDeletedModels` trait to all models whose attributes should be written to `deleted_models` whenever the model is deleted.
```php
use Illuminate\Database\Eloquent\Model;
use Spatie\DeletedModels\Models\Concerns\KeepsDeletedModels;class BlogPost extends Model
{
use KeepsDeletedModels;
}
```With this in place, the attributes will be written to `deleted_models` when the model is deleted.
```php
$blogPost = BlogPost::find(5);$blogPost->delete(); // values will be copied to the `deleted_models` table.
```To restore a previous model you can call `restore` and pass the id.
```php
$blogPost = BlogPost::restore(5); // $blogPost will be restored and returned
```If the model to be restored can't be found in the `deleted_models` table, a `Spatie\DeletedModels\Exceptions\NoModelFoundToRestore` exception will be thrown.
### Restoring without saving
To restore in memory, without actually saving it, you can call `makeRestored`.
Keep in mind that calling this method will also remove the record in the `deleted_models_table`.```php
// $blogPost will be return, but it is not saved in the db yet
$blogPost = Blogpost::makeRestored($id);$blogPost->save();
```If the model to be restored can't be found in the `deleted_models` table, `null` will be returned by `makeRestored`.
### Restoring without emitting events
By default, the `Spatie\DeletedModels\Events\RestoringDeletedModelEvent` and `Spatie\DeletedModels\Events\DeletedModelEvent` will be dispatched when calling `restore` on a model.
If you don't want these events to be dispatched, call `restoreQuietly`.
```php
BlogPost::restoreQuietly(); // no events will be dispatched
```### Customizing the restore process
#### Using closures passed to `restore`
The `restore` function accepts a callable as the second argument. The `beforeSaving` callable will be executed when the restored model was created in memory, but before saving it in the db.
```php
BlogPost::restore(5, function(BlogPost $post, DeletedModel $deletedModel) {
$post->title = "{$post->title} (restored)";
})
```#### Using methods on the model
If you need to run some logic to before and after restoring a model, you can implement `beforeRestoringModel` and `afterRestoringModel` on your model.
```php
use Illuminate\Database\Eloquent\Model;
use Spatie\DeletedModels\Models\Concerns\KeepsDeletedModels;class BlogPost extends Model
{
use KeepsDeletedModels;
public static function beforeRestoringModel(DeletedModel $deletedModel): void
{
// this will be executed right before restoring a model
}public static function afterRestoringModel(
Model $restoredMode,
DeletedModel $deletedModel
): void
{
// this will be executed right after restoring a model
}
}
```To determine which attributes and values should be kept in `deleted_models`, you can implement `attributesToKeep`
```php
use Illuminate\Database\Eloquent\Model;
use Spatie\DeletedModels\Models\Concerns\KeepsDeletedModels;class BlogPost extends Model
{
use KeepsDeletedModels;
public function attributesToKeep(): array
{
// here you can customize which values should be kept. This is
// the default implementation.
return $this->toArray();
}
}
```### Pruning deleted models
After a while, the `deleted_models` table can become large. The `DeletedModel` implements [Laravel's native `MassPrunable` trait](https://laravel.com/docs/9.x/eloquent#pruning-models).
You can configure the number of days records in the `deleted_models` will be pruned in the `prune_after_days` key of the `deleted-models.php` config file. By default, all deleted models will be kept for 365 days.
Don't forget to schedule the `model:prune` as instructed [in Laravel's docs](https://laravel.com/docs/9.x/eloquent#pruning-models).
### Low-level customization of the delete and restoration process
The `DeletedModel` model implements most logic to keep and restore deleted models. You can modify any of the behaviour by creating a class that extends `Spatie\DeletedModels\Models\DeletedModel`. You should put the class name of your extended class in the `model` key of the `deleted-models.php` config file.
With this in place you can override any of the methods in `DeletedModel`.
```php
use Spatie\DeletedModels\Models\DeletedModel;class CustomDeletedModel extends DeletedModel
{
protected function makeRestoredModel(string $modelClass): mixed
{
// add custom logic
return parent::makeRestoredModel($modelClass)
}
}
```## Testing
```bash
composer test
```## Changelog
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
## Contributing
Please see [CONTRIBUTING](CONTRIBUTING.md) for details.
## Security Vulnerabilities
Please review [our security policy](../../security/policy) on how to report security vulnerabilities.
## Credits
- [Freek Van der Herten](https://github.com/freekmurze)
- [All Contributors](../../contributors)This package was inspired by these two blog posts:
- [Easy, alternative soft deletion](https://brandur.org/fragments/deleted-record-insert)
- [this one](Soft Deletion Probably Isn't Worth It).## License
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.