使用updateOrCreate方法更新一对多关系

问题描述 投票:5回答:2

我的主要模型TagProduct有一对多的关系,其中一个Tag可以通过DB上的Products关系分配给他们的许多tag_id

在我的编辑视图中,我允许用户编辑标签products。可以在表单请求中添加/编辑/删除这些产品。

表格上的每个product字段都是从request()数组中获取的。例如:request('title'),request('price')

例如,我将$title[$key]设置为request('title')数组。

接下来我的想法是根据请求数据循环遍历每个products这个tagupdateOrCreate。这里的问题是,没有办法检测特定的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,但如果尚未更新,则不会删除现有产品图像。谢谢!

php laravel eloquent
2个回答
2
投票

按照我的观点,你走错了路。标记关系应该是多对多。

您必须在ManyToMany关系中查看Laravel的sync()方法。请检查: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
投票

通常我会在前端做类似的事情

<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>

使用javascript创建json(产品对象数组)有效负载,并将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'}]

现在在后端,遍历产品列表并检查操作。根据行动,采取必要步骤。

© www.soinside.com 2019 - 2024. All rights reserved.