Php 如何在Laravel中更新雄辩(有很多关系)

Php 如何在Laravel中更新雄辩(有很多关系),php,laravel,Php,Laravel,我有两个模块,分别是产品模块和项目模块。这两个模块之间的关系是:产品有许多项目,项目属于产品 产品模块的表为:id、产品名称项目模块的表为:id、产品id、项目名称、数量、价格 这是我的更新代码 public function update(Request $request) { $product = Product::findOrFail($id); $product->product_name = $request->product_name; $prod

我有两个模块,分别是产品模块和项目模块。这两个模块之间的关系是:产品有许多项目,项目属于产品

产品模块的表为:id、产品名称项目模块的表为:id、产品id、项目名称、数量、价格

这是我的更新代码

public function update(Request $request)
{
    $product = Product::findOrFail($id);
    $product->product_name = $request->product_name;
    $product->update();
    // Remove all items and add new
    $product->items()->delete();
    // Save each items
    if($request->get('item_name')){
        foreach($request->get('item_name') as $key => $item_name)
        {   
            $items = new Items();
            $items->products_id = $product->id;
            $items->item_name = $item_name;
            $items->quantity = $request->quantity[$key];
            $items->price = $request->price[$key];
            $items->save();
        };
    };
}
此更新代码的结构是每当有更新时,每个项目都将被删除,更新信息将作为新行添加

我想要的是,这些项目不应该被删除,并添加为新的。这是因为我想维护项目ID。我应该对当前代码修改什么?

尝试更新或创建函数,以便更新相同的名称,否则它将创建新的条目,或者您可以向第一个数组添加任何唯一的ID,并根据该数组更新laravel

参考链接

公共函数updateRequest$请求 { $product=product::findOrFail$id; $product->product\U name=$request->product\U name; $product->update; //保存每个项目 如果$request->get'item\u name'{ foreach$request->get'item\u name'as$key=>$item\u name{ Items::updateOrCreate[ item_name=>$item_name, products\u id=>$product->id,//如果您希望每个产品id具有唯一的名称,请在此处添加 ], [ 数量=>$request->数量[$key], 价格=>$request->price[$key] ]; }; }; }
如果您的目的是使添加、删除和更新项目更具动态性,我们必须以另一种方式处理此问题! 不幸的是,Laravel并没有提供像sync这样的方法来处理多对一关系,而只是多对多关系。因此,您必须在代码中插入一些额外的逻辑。我们将使用id键来处理这个逻辑。因此,对于这项工作,来自请求的所有产品项都必须具有密钥id。数据库中尚不存在的新项的id密钥必须为空

例如:

[
  {
    "id": 1,
    "name": "Item 1",
    "quantity": 2,
    "price": 10,
    "product_id": 1,
  },
  {
    "id": "",
    "name": "Item 2",
    "quantity": 3,
    "price": 22,
    "product_id": 1,
  },
  {
    "id": "",
    "name": "Item 3",
    "quantity": 9,
    "price": 33,
    "product_id": 1,
  }
]
注意,只更新第一个项目,添加第二个和第三个项目,因为id键为空,并且将删除不进入数组但存在于数据库中的项目

那么,我们走吧

1-为id为的项、id为的项和id为的项创建3个辅助变量。请注意,我们使用collect方法帮助我们处理数组:

$items_without_id = collect($items)->where('id', '');
$items_with_id = (clone collect($items))->where('id', '!=', '');
$items_ids = $items_with_id->pluck('id');
2-使用id更新项目:

foreach ($items_with_id as $item) {
   $obj = App\ProductItem::find($item['id']);
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->save();
}
3-删除未进入阵列的项目,我们假设必须删除这些项目:

$product->items()->whereNotIn('id', $items_ids)->delete();
4-最后插入没有id的项目。我们认为必须添加这些项目:

$items_without_id->each(function ($item) use ($product) {
   $obj = new App\ProductItem();
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->product_id = $product->id;
   $obj->save();
});
完整代码:

$product = App\Product::findOrFail($id);
$items = $request->items;

$items_without_id = collect($items)->where('id', '');
$items_with_id = (clone collect($items))->where('id', '!=', '');
$items_ids = $items_with_id->pluck('id');

foreach ($items_with_id as $item) {
   $obj = App\ProductItem::find($item['id']);
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->save();
}

$product->items()->whereNotIn('id', $items_ids)->delete();

$items_without_id->each(function ($item) use ($product) {
   $obj = new App\ProductItem();
   $obj->name = $item['name'];
   $obj->price = $item['price'];
   $obj->quantity = $item['quantity'];
   $obj->product_id = $product->id;
   $obj->save();
});
邮递员测试:


希望这有帮助。对不起,我的英语不好。

也许只是删除这个$product->items->delete;假设您已经设置了很多关系,要检索产品项,只需使用product::find1->items;这样地?Product::find$id->items@AlzafanChristian不起作用..您应该在视图中的请求集合中将项目id作为数组发送。然后在for循环中通过item id更新特定的item信息。您没有理解我的意思,如果只是更新产品,就不需要删除关系或创建新的项。然后,如果要添加新项,请将外键添加到父主键。这就是问题所在clue@MOHAMMADABUKAWSAR建议有效,非常感谢。也谢谢你Alzafan Christianops抱歉让我来解决这个问题是的当然KamleshPaulit已经解决了。。感谢youu@RamadhaniBaharzah那么请把这个标记为你的答案