Удаление – самое простое действие в обычном CRUD. Ему не нужен шаблон, все удаление состоит из простого обработчика, в котором даже нет условных конструкций.
Маршрут:
<?php
Route::delete('articles/{id}', [ArticleController::class, 'destroy'])
->name('articles.destroy');
Обработчик:
<?php
// Не забывайте про авторизацию (здесь не рассматривается)
// Удаление должно быть доступно только тем, кто может его выполнять
public function destroy($id)
{
// DELETE — идемпотентный метод, поэтому результат операции всегда один и тот же
$article = Article::find($id);
if ($article) {
$article->delete();
}
return redirect()->route('articles.index');
}
Самое интересное в удалении – это ссылка или кнопка удаления. Она не может быть обычной ссылкой. Почему? Потому что, с точки зрения HTTP, удаление это DELETE-запрос. Эту семантику важно соблюдать, так как на нее ориентируются разные инструменты и поисковики при анализе страниц. Если сделать удаление обычной ссылкой, то любой автоматический инструмент может попробовать перейти по ней (например предзагрузка страниц в chrome). Это будет крайне неприятный сюрприз.
Как минимум для разрешения подобных ситуаций нужно использовать атрибут rel:
<a href="..." rel="nofollow">Удалить</a>
Но этого недостаточно для отправки DELETE-запроса. Правильно реализовать эту ссылку формой, которая не отправляет никаких данных, но шлет верный запрос. В принципе так и можно поступить, но возникает странная ситуация. Само удаление содержит меньше кода чем кнопка по удалению. Да и шаблоны становятся очень грязными.
Избежать ручного создания такой формы можно с помощью библиотеки jquery-ujs, которая изначально была написана для Rails, но не ограничена этим фреймворком. Эта библиотека написана на JS и подключается во фронтенд-части. Она опирается на data-атрибуты и сама превращает в форму все что ее попросят. Для ее установки, наберите в директории проекта:
# Убедитесь в том, что у вас установлена Node.js
node -v
v13.7.0 # Ваша версия может отличаться
# Установите зависимости
npm install @rails/ujs
# Для установки остальных пакетов
npm install
Затем добавьте в конец файла resources/js/app.js строчки:
import ujs from '@rails/ujs';
ujs.start();
И запустите сборку фронтенда:
npm run dev
Теперь попробуем использовать эту библиотеку:
<a href="..." data-method="delete" rel="nofollow">Удалить</a>
Библиотека подключенная к странице, проанализирует все ссылки с нужными data-атрибутами и превратит их в формы отправляющие указанные запросы. Эти запросы могут быть любыми, хоть DELETE, хоть PATCH.
Кроме того, с ее помощью можно блокировать кнопки и вызывать подтверждение:
<a href="..." data-confirm="Вы уверены?" data-method="delete" rel="nofollow">Удалить</a>
<input type="submit" value="Сохранить" data-disable-with="Сохраняем">
Зависимости
В реальной жизни удаление не такая простая операция. Обычно сущности не существуют сами по себе, у них есть зависимости. Например, у статьи есть комментарии, а у курса — уроки. Как должна вести себя система при удалении родительской сущности? Что делать с зависимостями?
Ответ будет разный для разных проектов и разных сущностей. Иногда нужно все удалить, иногда разорвать связи. В более сложных ситуациях удалять нельзя вообще и тогда используется "мягкое удаление". При таком подходе сущность просто помечается как удаленная и не выводится на сайте, но всегда есть возможность ее восстановить.
Самостоятельная работа
- Реализуйте удаление
- Добавьте в список статей ссылку на удаление каждой статьи.
- Попробуйте самостоятельно добавить вывод флеш-сообщений.
Дополнительные материалы
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.