首页 > 解决方案 > 在 Laravel 中使用 Eloquent 更新一对多关系

问题描述

我对 Laravel 比较陌生。我试图弄清楚如何在 Eloquent ORM 中使用事务,尤其是在关系方面。

假设我在两个表之间有一对多的关系:RecipesIngredients,分别。

一个食谱(及其成分)如下所示:

[
    'id' => 1,
    'name' => 'Lasagna',
    'readyIn' => '30 minutes',
    'ingredients' => [
        ['id' => 1, 'name' => 'noodles', 'quantity' => '8'],
        ['id' => 2, 'name' => 'cheese', 'quantity' => '2 cups']
    ]
]

更新现有配方时,我收到的请求是:

[
    'id' => 1,
    'name' => 'Lasagna',
    'readyIn' => '1 hour',
    'ingredients' => [
        ['id' => 1, 'name' => 'noodles', 'quantity' => '9'],
        ['id' => 2, 'name' => 'mozarella cheese', 'quantity' => '3 cups'],
        ['id' => null, 'name' => 'sauce', 'quantity' => '1 jar'],
        ['id' => null, 'name' => 'onion', 'quantity' => '1']
    ]
]

我的方法是执行以下操作来更新配方:

DB::transaction(function() use ($request, $id) {
    // update existing recipe
    $recipe = Recipe::find($id);
    $recipe->fill($request->all());
    $recipe->save();

    // get old & new ingredients
    $oldIngredients = $recipe->ingredients();
    $newIngredients = $request->get('ingredients');

    // delete old ingredients that do not appear in the new list
    if ($ids = array_diff(
        array_pluck($oldIngredients, 'id'),
        array_pluck($newIngredients, 'id')
    )) {
        Ingredient::destroy($ids);
    }

    // save new ingredients
    foreach ($newIngredients as $attributes) {
        // update existing ingredient
        if ($id = array_pull($attributes, 'id')) {
            $ingredient = Ingredient::find($id);
            $ingredient->fill($attributes);
            $ingredient->save(); 
        // create new ingredient
        } else {
            $recipe->ingredients()->create($attributes);
        }
    }
});

Ingredients根据我的理解,使用这种方法,表中的那些和$recipe's 的成分之间不会有脱节吗?与 in 一样Ingredient::destroy($ids)$ingredient->save()仅更改Ingredients表中的记录,但不更改$recipe's 成分。如果是这样,有没有办法在$recipe我更新或删除成分时更新?我的目标是在交易完成后进行更新,$recipe包括其成分。

标签: phplaraveltransactionseloquentone-to-many

解决方案


推荐阅读