Логика сохранения тегов для поста. PHP
Нужно в админке при создании поста добавить к нему теги.
Есть три таблицы в БД posts, tags, post_has_tags
. Связь belongsToMany()
Обычно реализовывал так:
- На фронте на input вешал js библиотеку например Tagify.
- При вводе названия отправлял запрос на бек для поиска подходящих тегов.
- На беке принимал массив с названиями тегов і через whereIn('name', array $tagNames) получал существующие теги.
- Не существующие сохранял в Бд и получал их идентификаторы
- Дальше привязывал новые и существующие теги по идентификаторам к посту
$post->tags()->attach(array_merge($tags, $new_tags))
КОд согранения на беке:
public function syncTags(array $tagNames): array
{
$tagModel = $this->tags()->getModel();
$existsTags = $tagModel::query()
->whereIn('name', $tagNames)
->get(['id', 'name']);
$newTags = array_diff($tagNames, $existsTags->pluck('name')->toArray());
$prepareInsert = array_map(function ($value) {
$title = trim($value);
return [
'name' => $title,
'slug' => Str::slug($title)
];
}, $newTags);
$tagModel::insert($prepareInsert);
$attachTags = $tagModel::query()->whereIn('name', $newTags)
->get(['id', 'name']);
$ids = $existsTags->merge($attachTags)->pluck('id')->toArray();
return $this->tags()->sync($ids);
}
На нынешнем проекте меня попросили переписать данный функционал, аргументировав это тем что нужно передавать на бек только идентификаторы так как поиск по именам не есть ОК. также и при поиске по slug. Есть вероятность, что либо, из-за ошибки кодировки либо еще чего мы создадим существующий тег.
На вопрос что делать с тегом которого нет в БД - Ответ: Создать метод API или с помощью livewire сохранять этот тег и возвращать его идентификатор на фронт и при сохранении поста отправлять только идентификаторы.
Либо при сохранении поста отправлять массив типа [new_tags=>[new_tag1], old_tag=>[tag1, tag2]]
.
Я посмотрел библиотеки для сохранения подобным вариантом на беке но там только варианты где принимают неймы а не идентификаторы. Например в библиотеке spatie/laravel-tags. И вот я пытаюсь розобратся почему и при каких обстоятельствах такое реально.. Может кто тоже так делает буду благодарен за пояснения
Дополнено
Реализовал с передачей идентификаторов. Как и ожидалось реализация сложнее. При отправке формы на сохранение я отправляю идентификаторы для существующих тегов и названия новых в отдельном инпуте tags[1,2,3], new_tags[tag 1, tag 2] После перезагрузки страницы при не удачной валидации я получаю только идентификаторы существующих тегов. Нужно для них откуда то взять имена. Отдельным запросом!? Теги подтягиваются при вводе названия путем Ajax. Отправлять пробовал [Old Name=>1, New New name=>null]. Но js библиотека понимает только два формата либо только имена, либо подготовленный массив который через инпут не передать. Отсюда нужно реализовывать конвертацию. Получать существующие теги по ID. Как по мне, подход сомнительный и не рациональный.
Почему прихожу к такому выводу!? Чем отличается получения тегов при вводе по имени (путем ajax) от поиска для сохранения после отправки формы. Как по мне ничем. Что в первом, что во втором случае получаем идентификаторы по имени. В первом при поиске, во втором после отправки формы.