Как правильно обработать ошибку внешнего ключа при добавлении записи в БД?

Teoretik

Новичок
Пример:
Пользователь хочет добавить на сайт статью и заполняет форму. Галочками отмечает теги, например, "MySQL", "базы данных". Нажимает кнопку сохранить.

На бекенде реализация следующая: таблицы articles, tags и таблица связей многие-ко-многим articles_to_tags. Перед добавлением записей в таблицу связей, я проверяю внешние ключи.

А теперь проблемная ситуация: пока пользователь писал статью, тег "базы данных" из таблицы tags кто-то удалил. Имею ошибку - внешний ключ невалиден.

Что делать? Вариант "молча проигнорировать плохое поле" не рассматривается.

Придумал несколько вариантов - но все плохие.
Ах да, в первую очередь интересует что делать для AJAX-форм.

1. сделать редирект на форму добавления, чтобы в списке тегов не было удаленного тега "базы данных". Плохо, ибо все введенные данные потеряются, особенно текст большой статьи.

2. вывести ошибку под списком чекбоксов - "тега с ID=100 БД больше нет". Плохо, ибо сообщение о невалидном ID для пользователя неинформативно, он даже не поймет какую галочку нужно убрать.

3. передать вместе ошибкой не только сообщение но и невалидный ID. Тогда js-скриптом можно снять галочку. Плохо, ибо пользователь снова может поставить галочку. И передача дополнительных параметров вместе с текстом ошибки усложняет всю обработку и на клиенте и на сервере.

4. убрать js-скриптом невалидный пункт. Сложно, ибо чтобы не попортить разметку нужно удалять не только чекбокс. А разметка на разных сайтах разная и писать каждый раз кастомный скрипт глупо.

Можно сказать что такая ситуация слишком редкая, не стоит заморачиватся и просто бросить fatal error. Но такой вариант мне не нравится.
 

Teoretik

Новичок
добавить тег "базы данных"...
Добавить тег нельзя по 2 причинам:

1. Когда пользователь нажимает кнопку сохранить - на сервер отправляется не список тегов, а список ID этих тегов (которые записаны в аттрибуте value тега checkbox). Поэтому обработчик на сервере самого названия тега не знает

Можно усложнить, и отправлять с помощью JS название + ID, то тогда имеем причину №2.

2. Внешний ключ может указывать на более сложную структуру. Например, у меня есть таблица стран, каждая из которых обязательно должна быть привязана к региону. Добавить страну динамически не могу, ибо привязку к региону должен указать пользователь.
Еще одна проблема многоязычнось - добавить тег можно только указав название на дефолтном языке (английский) + на других по желанию. Писать "базы данных" в английскую версию названия неправильно.

Вопрос касается внешних ключей вообще, а пример с тегами приведен для простоты.
 

Semen

Семён
значит сохранить статью и показать сообщение, что такой тег был удалён и не будет применён к этой статье.
 

fixxxer

К.О.
Партнер клуба
Мне не очень понятен вопрос.
Технически - целостность базы обеспечивается через CONSTRAINT FOREIGN KEY.
Как обработать ситуацию, когда СУБД отдает ошибку - это зависит от постановки задачи. Кто ставит задачи - у того и спросить, как такая ситуация должна выглядеть снаружи для пользователя. В зависимости от ответа уже решать, как это реализовать технически.
 
Сверху