Удаление записей из базы в Laravel Eloquent

Eloquent – это объектно-реляционный преобразователь (ORM), который включен в структуру Laravel по умолчанию. В этой серии статей вы узнаете, как делать запросы к базе данных и как работать с отношениями в Laravel Eloquent. Также вы сможете попрактиковаться на примерах: мы попробуем улучшить демо-приложение с помощью новых моделей и отношений.

Примечание: Остальные мануалы данной серии можно найти по тегу Laravel Eloquent.

Удалять записи из базы данных в Eloquent очень удобно – это делается с помощью специального метода delete внутри родительского класса Model. Команда link:delete, уже реализованная в базовой версии нашего демо-приложения, удаляет ссылки по id. Однако в приложении по-прежнему отсутствует команда для удаления списков.

В последней части этой серии мы создадим новую команду для удаления списков.

Примечание: Для простоты после удаления списка все ссылки, связанные с ним, будут присвоены списку по умолчанию.

Откройте терминал и запустите следующую команду, чтобы создать новую команду Artisan:

docker-compose exec app php artisan make:command ListDelete

Это создаст новый файл ListDelete.php, расположенный в app/Console/Commands. Откройте файл в любом редакторе кода:

app/Console/Commands/ListDelete.php

Давайте обновим стандартный код команды, чтобы она могла обрабатывать удаление списка по его уникальному слагу (который представляет собой понятный URL).

Вот что должен делать наш метод handle():

  • Получив предоставленный пользователем слаг, проверить наличие списка с данным слагом в базе данных.
  • Если списка с таким слагом нет, отобразить сообщение об ошибке и завершить работу.
  • Если список найден, попросить пользователя подтвердить операцию.
  • Присвоить списку по умолчанию все ссылки, принадлежащие списку, который нужно удалить.
  • Удалить список из базы данных.

Если вы выполнили все предыдущие части этой серии, значит, вы уже делали подобное при создании команды LinkUpdate. Основное отличие в данной ситуации состоит в том, что вам не нужно запрашивать у пользователя дополнительную информацию, а нужно запустить обновление перед запуском метода delete(), чтобы передать соответствующие ссылки другому списку.

Замените стандартный код в файле ListDelete.php следующим кодом:

<?php

namespace App\Console\Commands;

use App\Models\Link;
use App\Models\LinkList;
use Illuminate\Console\Command;

class ListDelete extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'list:delete {list_slug}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Delete Lists';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $list_slug = $this->argument('list_slug');
        $list = LinkList::firstWhere('slug', $list_slug);

        if ($list === null) {
            $this->error("Invalid or non-existent List.");
            return 1;
        }

        if ($this->confirm("Confirm deleting the list '$list->title'? Links will be reassigned to the default list.")) {
            $default_list = LinkList::firstWhere('slug', 'default');
            if (!$default_list) {
                $default_list = new LinkList();
                $default_list->title = 'default';
                $default_list->slug = 'default';
                $default_list->save();
            }

            $this->info("Reassigning links to default list...");

            Link::where('link_list_id', $list->id)->update(['link_list_id' => $default_list->id]);

            $list->delete();
            $this->info("List Deleted.");
        }

        return 0;
    }
}

Сохраните и закройте файл.

Согласно нашему новому коду, метод handle() сначала пробует найти список ссылок на основе предоставленного слага. Если такой список не обнаружен, приложение завершает работу с ошибкой. Если же такой список найден, приложение вызывает метод confirm(), который запрашивает у пользователя подтверждение.

После подтверждения приложение найдет список по умолчанию (а при необходимости и создаст новый, присвоив его переменной $default_list).

Затем оно найдет и обновит все ссылки, принадлежащие списку, который будет удален. Связанный вызов update() изменит ID списка для всех ссылок, соответствующих запросу, используя условие, определенное в предыдущем вызове where(). Эта строка выделена в коде для удобства.

В конце процесса список удаляется с помощью метода delete(), – его мы тоже выделили красным. Этот метод доступен для всех моделей Eloquent через родительский класс Model.

Чтобы удалить список, сначала запустим link:show.

docker-compose exec app php artisan link:show

Эта команда вернет все ссылки, находящиеся в настоящее время в базе данных:

+----+-------------------------------------------------+--------------+----------------------------------+
| id | url                                             | list         | description                      |
+----+-------------------------------------------------+--------------+----------------------------------+
| 1  | https://digitalocean.com/community              | digitalocean | DO Community                     |
| 2  | https://digitalocean.com/community/tags/laravel | digitalocean | Laravel Tutorias at DigitalOcean |
| 3  | https://digitalocean.com/community/tags/php     | digitalocean | PHP Tutorials at DigitalOcean    |
| 4  | https://twitter.com/digitalocean                | social       | Twitter                          |
| 5  | https://dev.to/digitalocean                     | social       | DEV.to                           |
| 6  | https://laravel.com/docs/8.x/eloquent           | default      | Laravel Eloquent Docs            |
+----+-------------------------------------------------+--------------+----------------------------------+

Чтобы удалить список из БД и вернуть его ссылки обратно в список по умолчанию, запустите:

docker-compose exec app php artisan list:delete digitalocean

Подтвердите операцию, нажав y и Enter.

Confirm deleting the list 'digitalocean'? Links will be reassigned to the default list. (yes/no) [no]:
 > y
Reassigning links to default list...
List Deleted.

Если вы снова запустите команду link:show, вы увидите обновленную информацию о списках:

+----+-------------------------------------------------+---------+----------------------------------+
| id | url                                             | list    | description                      |
+----+-------------------------------------------------+---------+----------------------------------+
| 1  | https://digitalocean.com/community              | default | DO Community                     |
| 2  | https://digitalocean.com/community/tags/laravel | default | Laravel Tutorias at DigitalOcean |
| 3  | https://digitalocean.com/community/tags/php     | default | PHP Tutorials at DigitalOcean    |
| 4  | https://twitter.com/erikaheidi                  | social  | Twitter                          |
| 5  | https://dev.to/erikaheidi                       | social  | DEV.to                           |
| 6  | https://laravel.com/docs/8.x/eloquent           | default | Laravel Eloquent Docs            |
+----+-------------------------------------------------+---------+----------------------------------+

Готово! Теперь в приложении появилась специальная команда для удаления списков, при этом она автоматически передает все ссылки из удаленного списка в список по умолчанию.

Tags: , ,

Добавить комментарий