php - 在 Laravel 中使用 Eloquent 更新一对多关系
问题描述
我对 Laravel 比较陌生。我试图弄清楚如何在 Eloquent ORM 中使用事务,尤其是在关系方面。
假设我在两个表之间有一对多的关系:Recipes
和Ingredients
,分别。
一个食谱(及其成分)如下所示:
[
'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
包括其成分。
解决方案
推荐阅读
- php - PSR-12 是否说明了命名空间导入和别名应该如何分组和排序?
- java - 在 MacOS 上将 spatialite 与 xerial/sqlite-jdbc 一起使用
- c++ - 打印 2D int 数组时从 'int' 到 'int**' [-fpermissive] 的无效转换
- react-native - 将 this.state 值转移到其他类 [React Native]
- azure - Azure Powershell 作业引发错误:操作返回了无效的状态代码“禁止”
- python - Python将XML解析为缺少元素的DataFrame
- ionic-framework - Formgroup 无法在表单提交 IONIC 5 上检索用户输入和页面重新加载的值
- scala - 数据框过滤掉包含指定单词的行(字符串)
- vbscript - 使用 VBS 扫描 \LOGS 子文件夹时出现问题
- ldap - 在 LDAP 上运行 RBAC 的 Apache Airflow