Search code examples
phpmysqllaravele-commercecart

UpdateOrCreate not working with array fields


here i am having the problem for to use UpdateOrCreate with Array,this is my Controller, here my extra_id is array field

 $cart =  Cart::updateOrCreate([
                            'user_id'=> $user_id,
                            'product_id'=>$id,
                            'attribute_id'=>$request->attribute_id,
                            'extra_id' => $request->extra_id,
                            ],
                            ['qty'=>DB::raw('qty + 1')]
                        );
   }

here i have used Casts to convert string into an array for that i have done this in my model,

protected $casts = [
    'extra_id'=>'array'
];

and as of problem if extra_id = [1,2] and again if same data comes up it create new record instead of updating quantity.


Solution

  • updateOrCreate method does not support querying using an array assigned to an attribute. It will not do a whereIn or, specially, whereJsonContains for json fields. It will always take the first element of the array and assign to a where condition.

    So, in your case as well, the produced query will always assign the first element of the array to the extra_id column.

    I would suggest to manually check for existence of the object, and then handle update and create separately.

    $cart = Cart::where(['user_id'=> $user_id,
                            'product_id'=>$id,
                            'attribute_id'=>$request->attribute_id,
                        ])
                  ->whereJsonContains('extra_id', $request->extra_id)
                  ->first();
    
    if( $cart ) //will be empty if no result
       $cart->update([
                      'qty' => DB::raw('qty + 1') 
                     ]);
    
    else
      $cart = Cart::create(['user_id'=> $user_id,
                            'product_id'=>$id,
                            'attribute_id'=>$request->attribute_id,
                            'extra_id' => $request->extra_id,
                            'qty' => 1
                           ]);