Моя основная модель Tag имеет отношение «один ко многим» с Product, где одному Tag может быть назначено много Products через отношение tag_id в БД.
В моем представлении редактирования я разрешаю пользователям редактировать тег products. Эти товары можно добавлять/редактировать/удалять в форме запроса.
Каждое поле product в форме берется из массива request(). Например: request('title'),request('price').
Например, я установил $title[$key] как массив request('title').
Мои мысли заключались в том, чтобы перебрать каждый из products для этого tag и updateOrCreate на основе данных запроса. Проблема здесь в том, что нет способа определить, действительно ли этот конкретный product нуждался в обновлении.
TagController — обновление модели продукта (один ко многим)
foreach($tag->products as $key => $product){
Product::updateOrCreate([
'id' => $product->id,
],
[
'title' => $title[$key],
'price' => $price[$key],
'detail' => $detail[$key],
'order' => $order[$key],
'tagX' => $tagX[$key],
'tagY' => $tagY[$key],
'thumb' => $img[$key],
]);
}
Для первоначального обновления tag я установил оператор if, который отлично работает (хотя и беспорядочно) для основного тега img.
TagController — обновление модели тегов
//Update the tag collection
if ($request->hasFile('img')) {
$tag->update([
'name' => $name,
'hashtag' => $hashtag,
'img' => $imgPub,
]);
} else{
$tag->update([
'name' => $name,
'hashtag' => $hashtag,
]);
}
Есть ли лучший способ определить, были ли обновлены поля product в запросе?
В идеале я хотел бы, чтобы пользователь мог добавлять/удалять или редактировать products из запроса на редактирование tag, но не удалять существующие изображения продукта, если они не были обновлены. Спасибо!






Обычно я делаю что-то подобное на стороне интерфейса
<div class = "product">
<!-- For Products that may be edited -->
<input type = "hidden" name = "id" value = {{$product->id??0}}>
<input type = "hidden" name = "action" value = "update">
<input type = "text" name = "title" value = {{$product->title}}>
...
</div>
<div class = "product">
<!-- For New Products -->
<input type = "hidden" name = "id" value=0>
<input type = "hidden" name = "action" value = "add">
<input type = "text" name = "title" value = "New Title">
...
</div>
<div class = "product">
<!-- For Deleted Products -->
<input type = "hidden" name = "id" value = {{$product->id}}>
<input type = "hidden" name = "action" value = "delete">
<input type = "text" name = "title" value = "New Title">
...
</div>
Создайте полезную нагрузку json (массив объектов продукта) с помощью javascript и отправьте запрос ajax на серверную часть.
[{'id':101,'title':'product 1','action':'update'},
{'id':102,'title':'product 2','action':'update'},
... ,
{'id':201,'action':'delete'},
{'id':202, 'action':'delete'},
... ,
{'id':0,'title':'new product 1','action':'add'},
{'id':0,'title':'new product 2','action':'add'}]
Теперь на стороне сервера прокрутите список продуктов и проверьте действие. В зависимости от действия, сделайте необходимый шаг.
На мой взгляд, вы на ложном пути. Отношение тегов должно быть Многие ко многим.
Вы должны проверить метод sync() Laravel в отношениях ManyToMany. Пожалуйста, проверьте это: https://laravel.com/docs/5.8/eloquent-relationships#many-to-many
Примечания: Добавьте коды в соответствии с вашей бизнес-логикой.
Продукт.php
public function products(){
return $this->belongsToMany( 'App\Product', 'product_tags', 'tag_id', 'product_id');
}
Тег.php
public function tags(){
return $this->belongsToMany( 'App\Tag', 'product_tags', 'product_id', 'tag_id');
}
ПродуктКонтроллер.php
public function update(Product $products, Request $request){
//update the product
$products->update($request->all());
//attach new tags to the product
$products->tags()->sync($request->input('tag_list'));
return redirect('articles');
}
Я не уверен, что это правильный подход. Одному products может быть назначено несколько tag, но products не может быть назначено более чем одному tag.
Я решил пойти с many to many, как предложил @mayank-dudakiya. Я использовал detach, а затем ->sync() для назначения сводной таблице. Я позволю пользователям обновлять products из отдельного представления, чтобы все было чище.
@scopeak Просто упомянем, что Eloquent предоставляет функцию syncWithoutDetach(), если вы хотите только прикрепить новые продукты, но не удалять существующие!
Рассматривали ли вы возможность добавления флага (столбца) в объект продукта. Таким образом, этот флаг устанавливается после обновления продукта и инициализируется обратно, когда вы выполняете нужное действие, когда продукт был обновлен?