简体   繁体   English

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

[英]Updating one-to-many relationships with updateOrCreate methods

My main model Tag has a one-to-many relationship with Product where one Tag can have many Products assigned to them via tag_id relationship on the DB. 我的主要模型TagProduct有一对多的关系,其中一个Tag可以通过DB上的tag_id关系tag_id分配许多Products

On my edit view, I am allowing users to edit the tag products . 在我的编辑视图中,我允许用户编辑标签products These products can be added/edited/deleted on the form request. 可以在表单请求中添加/编辑/删除这些产品。

Each product field on the form is picked up from a request() array. 表单上的每个product字段都从request()数组中获取。 Eg: request('title'),request('price') . 例如: request('title'),request('price')

I have set $title[$key] as the request('title') array for example. 我已将$title[$key]request('title')数组。

My thoughts next, was to loop through each of the products for this tag and updateOrCreate based on the request data. 接下来我的想法是根据请求数据循环遍历此tag每个productsupdateOrCreate The issue here, is that there's no way of detecting if that particular product was indeed needing updated. 这里的问题是,没有办法检测特定product是否确实需要更新。

TagController - Update Product Model (One-to-Many) 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],
   ]);
}

For the initial tag update, I have set an if statement which works great (albeit messy) for the main tag img . 对于初始tag更新,我设置了一个if语句,它对主标签img起作用很好(尽管很麻烦)。

TagController - Update Tag Model TagController - 更新标记模型

//Update the tag collection
if($request->hasFile('img')) {
  $tag->update([
    'name' => $name,
    'hashtag' => $hashtag,
    'img' => $imgPub,
  ]);
} else{
  $tag->update([
    'name' => $name,
    'hashtag' => $hashtag,
  ]);
}

Is there a better way to determine if the product fields were updated on the request? 有没有更好的方法来确定product字段是否在请求中更新?

Ideally I would like the user to be able to add/remove or edit products from the tag edit request, but not delete existing product images if they have not been updated. 我非常希望用户能够添加/删除或编辑productstag编辑请求,但如果他们没有被更新,不删除现有的产品图片。 Thanks! 谢谢!

As per my view, you are on the wrong track. 按照我的观点,你走错了路。 Tagging relationship should be Many To Many. 标记关系应该是多对多。

You must check about sync() method of Laravel in ManyToMany relationship. 您必须在ManyToMany关系中检查Laravel的sync()方法。 Please check this: https://laravel.com/docs/5.8/eloquent-relationships#many-to-many 请查看: https//laravel.com/docs/5.8/eloquent-relationships#many-to-many

Notes: Please add codes as per your business logic. 注意:请根据您的业务逻辑添加代码。

Product.php Product.php

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

Tag.php Tag.php

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

ProductController.php 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');
 }

Normally I do something similar on the frontend side 通常我会在前端做类似的事情

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

Create the json (array of product objects) payload using javascript and send ajax request to the backend 使用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'}]

Now on the backend side, loop through the list of products and check for action. 现在在后端,遍历产品列表并检查操作。 Depending on the action, take necessary step. 根据行动,采取必要步骤。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM