如何停止重复条目插入,而在laravel 8数据库更新?



我在laravel中更新数组时遇到了一个问题。

问题是,我在template_idoption_id之间有多对多的关系。以下是product_template_options的迁移文件:

public function up()
{
Schema::create('product_template_options', function (Blueprint $table) {
$table->engine = "InnoDB";

$table->id();
$table->unsignedBigInteger('template_id');
$table->unsignedBigInteger('option_id');
$table->boolean('is_active')->default('1');
$table->foreign('template_id')->references('id')->on('product_templates');
$table->foreign('option_id')->references('id')->on('product_options');
$table->timestamps();
$table->softDeletes();
});

}

现在主要的事情是我能够插入与template_id相关的新option_id

更新时,意味着删除一些以前的option_id并添加一些新的option_id。当删除一些以前的option_id时,我可以从数据库中删除它。在插入new时,我也可以插入new,但主要的是我也会得到一些重复的条目,比如在phpmyadmin中,我试着像这样通过邮差插入,在这里你可以看到我没有删除option_id = 1,但删除了一些以前的option_id = like [2,3]。但是,我得到了option_id = 1的重复条目。

我如何阻止它被插入数据库,而更新数组?下面是更新选项的代码:

/**
* update Options into Template 
* @param  IlluminateHttpRequest  $request
* @param  AppModelsProductTemplateOption  $ProductTemplateOption
* @return IlluminateHttpResponse
* @param  int $Template_id 
* 
*/
public function UpdateOptions(Request $request,$Template_id,ProductTemplateOption $ProductTemplateOption)
{

$input = $request->all();

// dd($input);
$validator = Validator::make($input, [
'option_id.*' => 'required | unique : product_template_options,option_id,'.$Template_id,
]);    

// dd($options);
if($validator->fails()){
return response()->json([
"message" => "validation failed",
]);
}
$Option_id = $request->input('option_id');
// dd($Option_id);

$FetchOptions = ProductTemplateOption::where('template_id',$Template_id)->pluck('option_id')->toArray();
// dd($FetchOptions);

$DifferencedOption = array_diff($FetchOptions,$Option_id);
// dd($DifferencedOption);
$RequestedOptions = array_diff($Option_id,$FetchOptions);
// dd($RequestedOptions);
if (count($DifferencedOption) > 0) {
ProductTemplateOption::whereNotIn('option_id',$Option_id)->where('template_id', $Template_id)->delete();
}
if (count($Option_id) > 0) {
foreach ($request->option_id as $Option_id => $options){
$HaveOptions =  ProductTemplateOption::where('template_id',$Template_id)->where('option_id','=',$options)->exists();
if ($HaveOptions === null) {
$ProductTemplateOption = new ProductTemplateOption;   
$ProductTemplateOption->template_id = $Template_id; 
$ProductTemplateOption->option_id = $options;
$ProductTemplateOption->is_active = 1;
$ProductTemplateOption->save();
}
else{
return false;
}
}
}

}

有谁能帮我做这个吗?

您可以在表迁移中应用复合unique键来防止重复:

$table->unique(['template_id', 'option_id'], 'template_option_unique_key');

您可能还需要添加一些验证来检查unique-ness,甚至在您访问数据库之前:

'template_id' => 'required|unique:product_template_options, template_id, NULL, NULL, option_id, ' . $request['option_id'],
'option_id.*' => 'required|unique:product_template_options, option_id, NULL, NULL, template_id, ' . $request['template_id'],

这个想法是检查给定的template_idoption_iduniqueoption_id.*检查option_id数组中的每个元素。

与其在更新时删除记录,不如在BelongsToMany关系上使用sync方法?

$model->relationship()->sync($option_ids);

最新更新