admin 管理员组文章数量: 1086019
I have a dynamic form fields
logic in my Livewire 3 class:
public properties:
public $steps = [
['image' => null, 'text' => null],
];
public $step = ['image' => null, 'text' => null];
Add/Remove step logic:
public function removeStep($index): void
{
unset($this->steps[$index]);// unset step
$this->steps = array_values($this->steps); // reshuffle indexes after deleting
}
public function addStep(): void
{
$this->steps[] = $this->step;
}
After adding all the necessary steps, they should be saved in the guide_steps
table:
guide_steps:
Schema::create('guide_steps', function (Blueprint $table) {
$table->id();
$table->foreignId('recipe_id')->constrained()->cascadeOnDelete();
$table->integer('step_number');
$table->text('step_text');
$table->string('step_image')->default('recipes-images/default/default_photo.png');
$table->timestamps();
$table->unique(['recipe_id', 'step_number']); // required for upsert()
});
Here is my approach for upserting new and updated steps, as well as removing steps that no longer exist in the new request:
upsertGroupedSteps:
public function upsertGroupedSteps($recipeId): void
{
$groupedSteps = collect($this->steps)->map(function ($step, $index) use ($recipeId){
return [
'recipe_id' => $recipeId,
'step_number' => $index + 1,
'step_text' => trim($step['text']),
'step_image' => $step['image']
? $step['image']->store('guides-images', 'public')
: 'recipes-images/default/default_photo.png',
'created_at' => now(),
'updated_at' => now(),
];
})->toArray();
// if recipeId != 0 it means we are updating existing steps
if ($this->recipeId != 0){
$newStepsNumbers = collect($groupedSteps)->pluck('step_number')->toArray();
GuideStep::where('recipe_id', $recipeId)
->whereNotIn('step_number', $newStepsNumbers)
->delete();
}
GuideStep::upsert(
$groupedSteps, ['recipe_id', 'step_number'], ['step_text', 'step_image']
);
}
Let’s say there are three steps with id
1, 2, and 3 in the guide_steps table. When I delete the step with id
2, logically, steps with id
1 and 3 should remain. However, the step with id
3 gets deleted, and its data is overwritten into the step with id
2. I didn’t expect this behavior and am not sure if it’s correct.
Here's what's happening:
- There were three steps numbered 1, 2, and 3.
- I am removing step 2 using
unset($this->steps[$index])
, and thenarray_values()
, which re-indexes the array. - As a result, step 3 becomes the second element of the array.
- When I am calling
upsertGroupedSteps()
, thestep_number
now goes from 1 to N again (without gaps). - The query
whereNotIn('step_number',$newStepsNumbers)->delete()
deletes all steps whosestep_number
doesn't match. - Consequently, only the first and the new second steps remain in the table, and the third step is lost.
本文标签:
版权声明:本文标题:php - How to avoid issues with step updates in upsertGroupedSteps caused by array reindexing when using dynamic fields? Livewire 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/p/1744074135a2529030.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论