Laravel Eloquent increment without updating timestamps

1.9k Views Asked by At

I have an Eloquent model on which I would like to increment a single attribute. So far I've been using the following line of code to achieve this:

Thread::where('id', $threadId)->increment('like_count');

This however has the unwanted side-effect of updating the updated_at timestamp. I've found the following way of updating a record without altering the timestamp:

    $thread = Thread::where('id', $threadId)->first();

    $thread->timestamps = false;
    $thread->like_count++;
    $thread->save();

But that suddenly looks a lot less concise. Therefore, I would like to know of there's a way to use the increment method without updating timestamps.

4

There are 4 best solutions below

5
Mihir Bhende On BEST ANSWER

If you do not need timestamps at all, you can disable it once for all for that particular model using :

public $timestamps = false; inside your model. This will add additional step that whenever you want the timestamps to be updated, you need to assign them value manually like $object->created_at = Carbon::now()

Secondly, if you want those disabled for particular query, then as you mentioned in your question is one way.

Another way is using query builder. Now timestamps is the functionality associated with Eloquent. However, if you update using simple query builder, it does not update timestamps on its own.

So you can do :

DB::table('threads')
            ->where('id', $threadId)
            ->update([ 'votes' => DB::raw('votes + 1') ]);

However, I will personally prefer using Eloquent way of doing this if given a choice.

Update

You can now pass additional parameter to increment function to specify what other columns you would like to update.

So this will become :

$thread = Thread::find($threadId);

$thread->increment('votes', 1, [
   'updated_at' => $thread->updated_at
]);
0
Zoli On

You could encapsulate the whole process into one method of the model.

0
Pomanh On

old thread but with laravel 7 and php7.4 you can do

Thread::where('id', $threadId)
->where(fn($q) => $q->getModel()->timestamps = false)
->increment('like_count');

older versions of php:

Thread::where('id', $threadId)
->where(function($q) {$q->getModel()->timestamps = false;})
->increment('like_count');
0
Luke Watts On

If you want to increment multiple rows at the same time and want to keep all the updated_at fields the same as they were you can do this:

Thread::whereIn('id', $ids)
->increment(
    'like_count',
    1, 
    ['updated_at' => DB::raw('updated_at')]
);