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 примером)