Laravel. Мягкое удаление (soft deletes)

17.11.2020

Теги: LaravelMySQLPHPWeb-разработкаБазаДанныхМиграцииТаблицаТеорияУдалитьФреймворк

Кроме обычного удаления записей из базы данных, Eloquent также умеет удалять модели без удаления. При таком удалении модель на самом деле остаётся в базе данных, но в таблице БД устанавливается атрибут deleted_at. Если у модели ненулевое значение deleted_at, значит было использовано псевдоудаление. Для включения soft deletes нужно использовать трейт Illuminate\Database\Eloquent\SoftDeletes и добавить столбец deleted_at в свойство $dates.

Пусть у нас есть модель Post постов блога. Создадим миграцию для добавления поля deleted_at:

> php artisan make:migration alter_posts_table --table=posts
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AlterPostsTable extends Migration {
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up() {
        Schema::table('posts', function (Blueprint $table) {
            $table->softDeletes();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down() {
        Schema::table('posts', function (Blueprint $table) {
            $table->dropSoftDeletes();
        });
    }
}
> php artisan migrate

Теперь добавляем в модель Post трейт SoftDeletes:

namespace App;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;

class Post extends Model {

    use SoftDeletes;

    /**
     * Атрибуты, которые должны быть преобразованы в дату
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}

Теперь при вызове метода delete, поле deleted_at будет установлено в значение текущей даты и времени. При запросе моделей, использующих мягкое удаление, «удалённые» модели не будут включены в результат запроса.

Для определения того, удалён ли на самом деле экземпляр модели, предназначен метод trashed():

if ($post->trashed()) {
    // пост не был удален, а был помещен в корзину
}

Для получения всех моделей, в том числе удалённых, предназначен метод withTrashed():

$posts = App\Post::withTrashed()
    ->where('user_id', auth()->user()->id)
    ->get();

Метод withTrashed() может быть использован в отношениях:

$post->comments()->withTrashed()->get();

Для получения только псевдоудалённых моделей предназначен метод onlyTrashed():

$flights = App\Post::onlyTrashed()
    ->where('user_id', auth()->user()->id)
    ->get();

Для восстановления псевдоудалённой модели предназначен метод restore():

$post->restore();

Этот метод можно использовать для восстановления нескольких моделей. Подобно другим массовым операциям, это не вызовет никаких событий для восстанавливаемых моделей.

App\Post::onlyTrashed()
    ->where('user_id', auth()->user()->id)
    ->restore();

Как и метод withTrashed(), метод restore можно использовать в отношениях:

$post->comments()->onlyTrashed()->restore();

Метод forceDelete() позволяет удалить псевдоуделенную модель уже по настоящему:

// Принудительное удаление одного экземпляра модели...
$post->forceDelete();
// Принудительное удаление всех связанных моделей...
$post->comments()->forceDelete();

Поиск: Laravel • MySQL • PHP • Web-разработка • База данных • Таблица • Теория • Удалить • Фреймворк • Миграции • SoftDelete

Каталог оборудования
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Производители
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Функциональные группы
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.