首页 > 解决方案 > 如何在 laravel 8 中更新数据库时停止插入重复条目?

问题描述

在 laravel 中更新数组时遇到问题。

template_id所以问题是,我在和之间有多对多的关系option_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();
    });
    
}

现在主要的是我能够插入option_idtemplate_id.

更新它时,意味着删除一些以前的内容option_id并添加一些新option_id内容。删除一些以前option_id的 时,我可以将其从数据库中删除。在插入新的同时我也可以插入新的,但主要是我也得到了一些重复的条目,就像在phpmyadmin中一样,我试图通过邮递员插入,在这里你可以看到我没有删除option_id = 1,但删除了一些以前option_id = like [2,3]的 . 但是,我收到重复的option_id = 1.

如何在更新数组时阻止它插入数据库?这是更新选项的代码:

   /**
 * update Options into Template 
 * @param  \Illuminate\Http\Request  $request
 * @param  \App\Models\ProductTemplateOption  $ProductTemplateOption
 * @return \Illuminate\Http\Response
 * @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;
            }
          }
    }
    

}

谁能帮助如何做到这一点?

标签: phpmysqllaravel

解决方案


您可以将复合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_idandoption_idunique。检查数组中的option_id.*每个元素。option_id

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

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

推荐阅读