Php 在Laravel中使用雄辩更新一对多关系
我对拉雷维尔比较陌生。我试图弄清楚如何使用有口才的ORM的事务,特别是在关系方面 假设两个表之间有一对多的关系:Php 在Laravel中使用雄辩更新一对多关系,php,laravel,transactions,eloquent,one-to-many,Php,Laravel,Transactions,Eloquent,One To Many,我对拉雷维尔比较陌生。我试图弄清楚如何使用有口才的ORM的事务,特别是在关系方面 假设两个表之间有一对多的关系:配方和成分 一种配方(含其成分)如下所示: [ 'id' => 1, 'name' => 'Lasagna', 'readyIn' => '30 minutes', 'ingredients' => [ ['id' => 1, 'name' => 'noodles', 'quantity' =>
配方
和成分
一种配方(含其成分)如下所示:
[
'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);
}
}
});
根据我的理解,使用这种方法,
成分表中的成分和$recipe
的成分之间会不会出现断开连接?与配料::销毁($id)
和$component->save()
一样,只更改配料表中的记录,而不更改$recipe
的配料。如果是,在我更新或删除配料时,是否有方法更新$recipe
?我的目标是在交易完成后更新$recipe
,包括其成分。我觉得这对于多对多
(多对多
)来说更有意义,因为一个配方可以有许多成分,每个成分都可以属于许多配方。您只需在两者之间使用一个轴心,并添加一个Quantity列。需要一些额外的逻辑来处理查找或创建,然后将配料附加到配方中,但使用一对多将导致潜在的重复配料,这似乎不正确(对我来说),您可以在之后重新加载关系:$Recipe->load('components')这就是你的意思吗?