Sandeep Sudhakaran
Sandeep Sudhakaran

Reputation: 1092

update timestamp in laravel model when timestamp set to false in more better way

I have set my three model's timestamp to false for not to update the updated_at column. now my update function need to update these three models. I wrote the function like below. and I felt it could have been done in more better way. can anyone help me for this.

I want to do it in this same function.

   public function update(
      BoxItemUpdateRequest $request,
      ModelA $modelA ,
      ModelB $modelB ,
      ModelC $modelC
   ) {
      $modelA->decrement(
         'total', 
          $request->quantity1- $request->quantity2
      );
      $modelA->timestamps = true;
      $modelA->touch();
      $modelA->save();
      $modelB->decrement(
        'total',
        $request->quantity1- $request->quantity2
      );
      $modelB->timestamps = true;
      $modelB->touch();
      $modelB->save();
      $modelC->quantity_accepted = $request->quantity2;
      $modelC->timestamps = false;
      $modelC->touch();
      $modelC->save();

      return Response::json([
        'status' => HttpStatusCode::HTTP_OK,
      ]);
   }

Thanks in advance.

Upvotes: 0

Views: 1223

Answers (2)

Mihir Bhende
Mihir Bhende

Reputation: 9055

By default, Eloquent expects created_at and updated_at columns to exist on your tables. If you do not wish to have these columns automatically managed by Eloquent, set the $timestamps property on your model to false

This means, if you are disabling the timestamps, you can still use pretty basic way of assigning a value manually to it. Switching the value of timestamps property to true or false is not a good way.

Why not use simply $modelB->updated_at = Carbon::now();? Since you have told laravel that you are managing the timestamps manually. This helps your code to be readable also if someone tries to see how the timestamps are updating manually,

You can do :

<?php 

public function update(BoxItemUpdateRequest $request, ModelA $modelA , ModelB $modelB , ModelC $modelC ) {

  $now = Carbon::now();
  $modelA->decrement('total', $request->quantity1- $request->quantity2);
  $modelA->created_at = $now;
  $modelA->updated_at = $now;
  $modelA->save();



  $modelB->decrement('total', $request->quantity1 - $request->quantity2);
  $modelB->created_at = $now;
  $modelB->updated_at = $now;
  $modelB->save();


  $modelC->quantity_accepted = $request->quantity2;
  $modelC->updated_at = $now;
  $modelC->save();

  return Response::json([
    'status' => HttpStatusCode::HTTP_OK,
  ]);
}

Upvotes: 0

Thomas Van der Veen
Thomas Van der Veen

Reputation: 3226

Maybe there are better solutions out there but you can make a trait for this that adds some more logic to the save() method or your model.

The trait could look like:

use Carbon;

trait DoesNotTouchTimestamps // Maybe not the best name
{    
    /**
     * Indicates if the model should be timestamped.
     *
     * @var bool
     */
    public $timestamps = false;

    /**
     * Save the model to the database.
     *
     * @param  array  $options
     * @return bool
     */
    public function save(array $options = [])
    {
        if (data_get($options, 'touch_updated_at', false)) {
            $this->updated_at = new Carbon;
        }

        return parent::save($options);
    }
}

Import it in your models:

use DoesNotTouchTimestamps;

class ModelA
{
    use DoesNotTouchTimestamps;
}

And call your save like:

$modelA->save([
    'touch_updated_at' => true,
]);

Upvotes: 1

Related Questions