Я относительно новичок в 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
.?Как и в Ingredient::destroy($ids)
и $ingredient->save()
, изменяются только записи в таблице Ingredients
, но не ингредиенты $recipe
.Если да, есть ли способ обновить $recipe
при обновлении или удалении ингредиентов?Моя цель - обновить $recipe
, включая его компоненты, после завершения транзакции.