Soft delete моделей в Laravel: подробное руководство
Оглавление
- Что такое soft delete
- Как настроить soft delete
- Как выполнить soft delete и проверить его
- Дополнительные хелперы для soft delete
- Как протестировать soft delete
- Как очистить старые soft delete модели
- Дополнительные материалы
Что такое soft delete
Soft delete позволяет разработчикам помечать модели как удалённые, не удаляя их из базы данных.
Представьте, что в вашей базе данных есть столбец deleted_at
, содержащий дату, когда запись была удалена.
Их главное преимущество заключается в том, что вы больше не теряете данные. Вы всегда сможете их восстановить.
Очевидно, что существует механизм, помогающий очистить старые soft delete модели, который я покажу вам позже.
Как настроить soft delete
Для настройки soft delete в Laravel необходимо выполнить два простых шага.
Сначала укажите, что вам нужен столбец для мягкого удаления в миграции (я написал статью о миграциях Laravel: Все секреты миграции). После выполнения миграции вы увидите новый столбец deleted_at
в таблице posts
.
public function up()
{
Schema::table('posts', function (Blueprint $table) {
$table->softDeletes();
});
}
В методе down()
вы можете удалить столбец с помощью метода dropSoftDeletes()
.
public function down()
{
Schema::table('posts', function (Blueprint $table) {
$table->dropSoftDeletes();
});
}
Затем в модели импортируйте трейт SoftDeletes
.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model
{
use HasFactory, SoftDeletes;
}
Как выполнить soft delete и проверить его
Для использования soft delete в Laravel вам не придётся менять свои привычки. Используйте метод delete()
вашей модели, как и раньше. Единственным отличием будет то, что Laravel добавит текущую дату и время в колонку deleted_at
.
$post->delete();
А если вы хотите проверить, была ли модель soft delete, я рекомендую использовать метод trashed()
, а не проверять вручную столбец deleted_at
.
if ($post->trashed()) {
//
}
Дополнительные хелперы для soft delete
Иногда вам может потребоваться включить в запросы soft delete модели. В этом может помочь функция withTrashed()
.
Post::withTrashed()->get();
Вы даже можете запрашивать только soft delete модели:
Post::onlyTrashed()->get();
Кроме того, поскольку модель на самом деле никогда не удаляется, вы можете восстановить её в любой момент с помощью метода restore()
. Столбец deleted_at
вернётся к значению NULL
.
$post->restore();
Наконец, если вы хотите действительно удалить soft delete модель из базы данных, используйте метод forceDelete()
.
$post->forceDelete();
Как протестировать soft delete
Чтобы протестировать Soft delete в Laravel, используйте метод assertSoftDeleted()
, предоставляемый Laravel.
Вот базовый пример того, как я бы поступил:
public function test_it_soft_deletes_posts()
{
$post = Post::factory()->create();
$this
->deleteJson(route('posts.destroy', $post))
->assertNoContent();
$this->assertSoftDeleted($post);
}
Существует и обратный метод — assertNotSoftDeleted()
.
Как очистить старые soft delete модели
Вы можете использовать механизм очистки, предлагаемый Laravel, для очистки старых soft delete моделей.
Например, импортируйте трейт Prunable
в свою модель и укажите фреймворку удалять модели, которые были soft delete в течение месяца или более.
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Prunable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
class Post extends Model
{
use HasFactory, Prunable, SoftDeletes;
public function prunable()
{
return static::where('deleted_at', '<=', now()->subMonth());
}
}
Не забудьте добавить команду model:prune
в планировщик задач. Добавьте её в файл app/Console/Kernel.php
:
protected function schedule(Schedule $schedule)
{
$schedule->command('model:prune')->daily();
}
На этом всё. Подробнее о планировщике задач вы можете узнать из статьи Laravel: Как работает cron и планировщик задач
Дополнительные материалы
- Laravel: Как работает cron и планировщик задач
- Laravel: Все секреты миграции
- Руководство по Soft Delete в Laravel
- Как использовать Soft Delete в Laravel Eloquent (c примером)