Обновление отношений один ко многим с помощью методов updateOrCreate - PullRequest
5 голосов
/ 10 марта 2019

Моя основная модель 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 на редактирование, но не удалять существующие изображения продуктов, если они не были обновлены. Спасибо!

Ответы [ 2 ]

2 голосов
/ 13 марта 2019

На мой взгляд, вы на неправильном пути. Отношения тегов должны быть Многие ко многим.

Вы должны проверить sync() метод Laravel в отношениях ManyToMany. Пожалуйста, проверьте это: https://laravel.com/docs/5.8/eloquent-relationships#many-to-many

Примечания: Пожалуйста, добавьте коды в соответствии с вашей бизнес-логикой.

product.php

  public function products(){
    return $this->belongsToMany( 'App\Product', 'product_tags', 'tag_id', 'product_id');
  }

Tag.php

   public function tags(){
     return $this->belongsToMany( 'App\Tag', 'product_tags', 'product_id', 'tag_id');
  }

ProductController.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');
 }
0 голосов
/ 13 марта 2019

Обычно я делаю что-то похожее на стороне интерфейса

<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'}]

Теперь на бэкэнд-стороне, переберите список продуктов и проверьте действие. В зависимости от действия сделайте необходимый шаг.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...