Reputation: 1113
Is it possible to update a user without touching the timestamps?
I don't want to disable the timestamps completly..
grtz
Upvotes: 105
Views: 91377
Reputation: 3388
Taken directly from the documentation.
If you would like to perform model operations without the model having its updated_at
timestamp modified, you may operate on the model within a closure given to the withoutTimestamps
method:
Model::withoutTimestamps(fn () => $post->increment(['reads']));
So in OP's case, the code will be something like this:
User::withoutTimestamps(function () {
$user = User::find(1);
$user->name = 'John';
$user->save();
});
Upvotes: 13
Reputation: 843
Laravel 8
Doing some overrides using seeders and on one test I have:
$item = Equipment::where('name', item_name))->first();
$item->description = 'some description';
$item->save(['timestamps' => false]);
Which works fine, but if I use firstOrNew
then the $item->save(['timestamps' => false]);
does not work.
// This does not work on Seeder file
$item = Model::firstOrNew(['name' => 'item_name']);
$item->description = 'some description';
$item->save(['timestamps' => false]);
// Doing the following works tho
$item = Model::firstOrNew(['name' => 'item_name']);
$item->description = 'some description';
$item->timestamps = false;
$item->save();
So in some cases you would use one over the other... Just check with die and dump to see whether +timestamps: false
$item->timestamps = false;
$item->save();
or
$item->save(['timestamps' => false]);
Edit:
In my project I opted using $item->timestamps = false;
so I would recommend using this as well. Here is a working snippet from laravelplayground:
https://laravelplayground.com/#/snippets/4ae950f2-d057-4fdc-a982-34aa7c9fee15
Check the HasTimestamps on Laravel api: https://laravel.com/api/8.x/Illuminate/Database/Eloquent/Concerns/HasTimestamps.html
and the save method on Model: https://laravel.com/api/8.x/Illuminate/Database/Eloquent/Model.html
The save method still accepts options but passing timestamps will not work.
Upvotes: -1
Reputation: 2184
For Larvel 5.1, you can also use this syntax:
Model::where('Y', 'X')
->update(['Y' => 'Z'], ['timestamps' => false]);
Upvotes: 4
Reputation: 12574
If you need to update single model queries:
$product->timestamps = false;
$product->save();
or
$product->save(['timestamps' => false]);
If you need to update multiple model queries use
DB::table('products')->...->update(...)
instead of
Product::...->update(...)
Upvotes: 20
Reputation: 261
Above samples works cool, but only for single object (only one row per time).
This is easy way how to temporarily disable timestamps if you want to update whole collection.
class Order extends Model
{
....
public function scopeWithoutTimestamps()
{
$this->timestamps = false;
return $this;
}
}
Now you can simply call something like this:
Order::withoutTimestamps()->leftJoin('customer_products','customer_products.order_id','=','orders.order_id')->update(array('orders.customer_product_id' => \DB::raw('customer_products.id')));
Upvotes: 25
Reputation: 4752
I ran into the situation of needing to do a mass update that involves a join, so updated_at
was causing duplicate column conflicts. I fixed it with this code without needing a scope:
$query->where(function (\Illuminate\Database\Eloquent\Builder $query) {
$query->getModel()->timestamps = false;
})
Upvotes: 6
Reputation: 2235
For Laravel 5.x users who are trying to perform a Model::update()
call, to make it work you can use
Model::where('example', $data)
->update([
'firstValue' => $newValue,
'updatedAt' => \DB::raw('updatedAt')
]);
As the Model::update function does not take a second argument anymore. ref: laravel 5.0 api
Tested and working on version 5.2.
Upvotes: 18
Reputation: 87719
Disable it temporarily:
$user = User::find(1);
$user->timestamps = false;
$user->age = 72;
$user->save();
You can optionally re-enable them after saving.
This is a Laravel 4 and 5 only feature and does not apply to Laravel 3.
Upvotes: 202
Reputation: 573
In Laravel 5.2
, you can set the public field $timestamps
to false
like this:
$user->timestamps = false;
$user->name = 'new name';
$user->save();
Or you can pass the options as a parameter of the save()
function :
$user->name = 'new name';
$user->save(['timestamps' => false]);
For a deeper understanding of how it works, you can have a look at the class \Illuminate\Database\Eloquent\Model
, in the method performUpdate(Builder $query, array $options = [])
:
protected function performUpdate(Builder $query, array $options = [])
// [...]
// First we need to create a fresh query instance and touch the creation and
// update timestamp on the model which are maintained by us for developer
// convenience. Then we will just continue saving the model instances.
if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
$this->updateTimestamps();
}
// [...]
The timestamps fields are updated only if the public property timestamps
equals true
or Arr::get($options, 'timestamps', true)
returns true
(which it does by default if the $options
array does not contain the key timestamps
).
As soon as one of these two returns false
, the timestamps
fields are not updated.
Upvotes: 33
Reputation: 1604
To add to Antonio Carlos Ribeiro's answer
If your code requires timestamps de-activation more than 50% of the time - maybe you should disable the auto update and manually access it.
In eloquent when you extend the eloquent model you can disable timestamp by putting
UPDATE
public $timestamps = false;
inside your model.
Upvotes: 20