Home > Back-end >  My query will not update, but when i refresh in dd it will
My query will not update, but when i refresh in dd it will

Time:05-25

When I run the query normally it won't update the status_order from 0 to 1, but when I put a dd() function after the query to check if it will update properly, it will give the same result the first time I run the code, but when I refresh the page it will update to a 1.

Here's how my code usually looks:

public function payment(Request $request){
      $total = 0;
      $orderInfo = $this->getOrderInfo();
      $json2 = array();
        foreach($this->getOrderInfo()->products as $product){
          $total  = ($product->price * $product->pivot->order_quantity);
        }
      if(Customer::find(Auth::user()->id)->balance >= $total && $orderInfo !== null){
        if($orderInfo->order_status !== 1){
        $orderInfo->where('customer_id', Auth::user()->id)
                  ->where('order_status', 0)
                  ->update(['order_status' => 1]);
      }
        foreach($orderInfo->products as $product){
          $json = array('order_id' => $product->pivot->order_id,
                        'product_id' => $product->pivot->product_id,
                        'product_name' => $product->name,
                        'price' => $product->price,
                        'quantity' => $product->pivot->order_quantity);
          array_push($json2, $json);
        }
        Customer::where('id', Auth::user()->id)->decrement('balance', $total);
        array_push($json2, array('order_status' => $orderInfo->order_status));
        $productInfo = json_encode($json2, JSON_PRETTY_PRINT);
        OrderHistory::create([
          'customer_id' => Auth::user()->id,
          'orderInfo' => $productInfo
        ]);
        $orderInfo->products()
        ->detach();
        $orderInfo->delete();
        return back();
      }else{
        return "Not enough balance";
      }
  }
}

Here's where I put my dd() function:

  if($orderInfo->order_status !== 1){
        $orderInfo->where('customer_id', Auth::user()->id)
                  ->where('order_status', 0)
                  ->update(['order_status' => 1]);
          dd($orderInfo->where('customer_id', Auth::user()->id)->where('order_status', 0));
      }

The if($orderInfo->order_status !== 1) is put in there for me to check if the query would get skipped at all. I have tried to alter the order in which the code is presented, but it didn't make any difference.

CodePudding user response:

this code produce mass update but doesn't affect your $orderInfo model which is loaded when it had order_status == 0

$orderInfo = $this->getOrderInfo();
// ...
$orderInfo->where('customer_id', Auth::user()->id)
                  ->where('order_status', 0)
                  ->update(['order_status' => 1]);
// in database data was updated, but $orderInfo is already in memory, so
// $orderInfo->order_status == 0

in case you want to get immediately impact on $orderInfo try

// if you order can have only one info
$orderInfo->order_status = 1;
$orderInfo->save();

// if order can have multiple info models
$orderInfo->newQuery()->where('customer_id', Auth::user()->id)
                  ->where('order_status', 0)
                  ->update(['order_status' => 1]);
$orderInfo = $orderInfo->fresh();

docs about fresh() method


as a sidenote here you're doing duplicate getOrderInfo() call

  $orderInfo = $this->getOrderInfo();
  $json2 = array();
  //foreach($this->getOrderInfo()->products as $product) {
  foreach($orderInfo->products as $product) {
    $total  = ($product->price * $product->pivot->order_quantity);
  }

update to clarify about comment to main post

truth to be told, i'm confused that this code runs at all. i meant $orderInfo is an object given you checked its property order_status but then you call where() on it as if it is a collection (or model). also its not laravel-query-builder but laravel-eloquent or just eloquent given you have detach() there.. – Bagus Tesa

if we dig into Illuminate\Database\Eloquent\Model class there is 'magic' method __call

/**
     * Handle dynamic method calls into the model.
     *
     * @param  string  $method
     * @param  array  $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        if (in_array($method, ['increment', 'decrement'])) {
            return $this->$method(...$parameters);
        }

        if ($resolver = (static::$relationResolvers[get_class($this)][$method] ?? null)) {
            return $resolver($this);
        }
        // that's why OP code works
        return $this->forwardCallTo($this->newQuery(), $method, $parameters);
    }

as you can see if model has no method to call it forwards call to Builder object (result of $this->newQuery()) which is equivalent to ModelName::query()

tbh, i agree that calling eloquent from loaded model is a bit frustrating, but it is 'by design'

CodePudding user response:

In order to do a mass update, what this theoretically is, you need to define all the attributes that you want to mass update in the $fillable array in your Model. (OrderInfo in this case)

  • Related