lundi 29 juin 2020

Queue New row insertion requests in Laravel to ensure server-side validation and avoid Duplicates

I have a table("product") with few column , say ID, brand_name, code, country_code and countrywise_serial_number, created_at, deleted_at.

I make a ajax call from webpage to insert values in table. The code I have written in backend is:

public function addProduct(Request $request){

    $brand_name = $request->brand_name;
  

    $sNo = DB::table('product')->where('country_code',101)->orderByDesc('countrywise_serial_number')->limit(1)->get();
    if($sNo->count()<1){
        $sNo=1;
    }else{
        $sNo= ($sNo[0]->countrywise_serial_number)+1;
    }
 
    $getDigit= 1;

    for($num=$sNo;$num>10;$num++){
        $num= $num/10;
        $getDigit++;

    }
    
    $zerosrequired= 7- $getDigit;
    $zeroes=str_repeat("0",$zerosrequired);
    $code="PRO"."IND".date("y")."MD".$zeroes.$sNo; //EG:PROIND20MD0000001

    // check if record already exist to avoid duplicate  entry
    $checkExistence=DB::table('product')->where(function($query) use($code){
        $query->where('code', $code);
        $query->whereNull('deleted_at');

    })
    ->orWhere(function($query) use($brand_name){
        $query->where('brand_name', $brand_name);
        $query->whereNull('deleted_at');

    })->get(); 
   
   
    if($checkExistence->count()>0){

        $existingData = array(
            'code' => $checkExistence[0]->code,
            'name' => $checkExistence[0]->brand_name,
           
        );
        return ['message'=> "Duplicate Warning" , 'name'=>$existingData['name'], 'code'=>$existingData['code']];
        

    }
    


    try{
    DB::table('product')->insert(
        ['code' => $code, 'brand_name' => $brand_name,'countrywise_serial_number'=>$sNo]
    );

    return ['message'=>true];
    }
     catch(\Exception $e){

        return  ['message'=>false];
     }
}

The problem is if I click submit button multiple times, multiple ajax requests are called and multiple rows with duplicate values are inserted(i.e. with same code and brandName) without any validation which should not happen.

I am worried if it will also happen if request is made from two or more device at the same time(with same values),

For avoiding multiple click to submit button I tried using:

$('#addsubmit').attr("disabled",true); //addsubmit is the submit button ID

and

$('#addsubmit').off("click");

but none of them are working; Here is the js code for ajax call:

$("#submit-product").submit(function(event){
    //submit-product is form ID

    //event.preventDefault();
    //event.returnValue = false;
    event.preventDefault ? event.preventDefault() : (event.returnValue = false);
    event.stopPropagation()

    
    
    var token = "";
    var formData={
        'brand_name' : $('#brand_name').val(),
        '_token': token
 
    };
    console.log(formData)
    $.ajax({
        type : 'post',
        data: formData,
        datatype: 'json',
        url: "",
        success: function(result){
            

            if (result.message=="Duplicate Warning"){
                $('#errormessage').html("") 
                $('#errormessage').css('color', 'red');
                console.log("if")
                if ($('#med_code').val()== result.code &&  $('#brand_name').val()==result.name)

                $('#errorDetails').html("Brand Name and Code already registered.")

                else if($('#med_code').val()== result.code)
                
                $('#errorDetails').html("product Code already in Use.")

                else
                $('#errorDetails').html("product already registered.")
                
                modalName ="add";
                //$('#deleteMessageImg').attr('src','')
                $('#add-products').modal('hide');
                $('#error-modal').modal('show');
            }

            else if(result.message){
                
                $('#add-products').modal('hide');
                $('#add-success-product').modal('show');
                $("#submit-product").trigger("reset");
            }
            
        }

        

    })
    

})

The server side validation part works fine if I insert record one by one i.e. after completion of one request.

Is there any way to let laravel finish one request at a time and then process another?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire