ctoma's avatar

Use ->update() without updating timestamps

So I have a query that updates many hundreds of rows at a time, eg

Model::where('something', '=', $something)->update(['status' => 'Unallocated']);

How can I run that query without updating the timestamps? I know that I could use the normal Query Builder instead, but I have certain model events that need to fire when this takes place too.

Is there any way to mass update, but not update the timestamps with Eloquent?

0 likes
18 replies
ctoma's avatar

@Prez Thanks for the reply! I tried that, and while that does work for save() it doesn't appear to work for update()

With update() I get: PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'timestamps' in 'field list'

wiedem's avatar

Besides what @Prez said, you can disable the timestamp touching very easily for each save/update operation:

Model::where('something', '=', $something)
    ->update(['status' => 'Unallocated'], ['timestamps' => false]);
2 likes
crabmusket's avatar

For the record, I just tried ->update(['status' => 'Unallocated'], ['timestamps' => false]); in a Laravel 5.3 app and it doesn't seem to be effective; my timestamps were still all updated.

The update method doesn't seem to take a second parameter any more.

orrd's avatar

Yeah, unfortunately it still doesn't have the second parameter any more and I couldn't find an alternative way to make it work. I ended having to use DB::table('products')->...->update(...) with the actual table name.

1 like
COTIGA's avatar

In LR5.7 Increment view count without change updatet_at

$post->update(['view_count' => $post->view_count + 1, 'updated_at' => false]);
jrdavidson's avatar

@oleg.khimich That would mean that on your post table migration you do not have an updated_at column. Can you share with us your migration file?

arukomp's avatar

If you'd like to disable timestamps on the whole Model, just include public $timestamps = false; property on your model class. Then it will not include created_at and updated_at columns in the queries.

2 likes
JeromeFitzpatrick's avatar

For anyone still looking for a solution and to answer the OP's original question, you can do either of the following (tested in Laravel 6):

// Instantiate the model and set the timestamps property to false
$post = new Post();
$post->timestamps = false;

// Then use the newModelQuery method to kick off your query
$post
    ->newModelQuery()
    ->where('something', '=', $something)
    ->update(['status' => 'Unallocated']);

OR

// When updating the timestamp, Laravel does an array merge
// so if you manually specify the updated_at column, it will 
// take precedence over the newly generated timestamp.
// So simply set update_as to its current value so it doesn't change

Post::where('something', '=', $something)
    ->update(
        ['status' => 'Unallocated', 'updated_at' => DB::raw('updated_at')]
    );

7 likes
untymage's avatar

anyone has better solution for this yet ?

Jatz's avatar

If you don't have timestamps columns, automatic updated_at can be disabled in the model.

/**
     * Disable the automatic updated_at.
     *
     * @var string
     */
    const UPDATED_AT = null;
himak's avatar

These options not work:

$user->update(['is_writer' => 1], ['timestamp' => false])
// or
$user->update(['is_writer' => 1], ['updated_at' => false])

These options work for me:

$user->is_writer = 1,
$user->timestamps = false
$user->save()

// or
$user->newModelQuery()->update([
    'writer' => $isWriter,
    'updated_at' => DB::raw('updated_at')
]);
1 like
nick_r's avatar

@himak because you should to use $user–>update(['timestamps' => false] instead timestamp->false

Chlouis's avatar

Hi ! I think the good answer is :

YourModel::withoutTimestamps(function() {
       YourModel::where('id', 42)->update(['name' => 'test']);
});
6 likes

Please or to participate in this conversation.