Apparently Laravel’s Eloquent update(['timestamps' => false])
option never worked in all cases so it was silently removed without any sort of deprecation notice or upgrade guide bullet point. It’s a good thing I pay close attention to every core pull request and also had an app-level integration test that confirmed the framework works as intended across each minor version upgrade.
Of course, I’m lying.
Laravel update() version control history
- [5.1] Feb 2016 So [‘timestamps’] doesn’t work
- [5.1] Mar 2016 Yeah, we should remove the [‘timestamps’] option
- [5.3] Mar 2016 [‘timestamps’] removed
- [5.3] Sept 2016 Restore it instead using [‘touch’]?
- [5.3] Dec 2016 Yeah, nah
The current $model->update(['touch' => false])
option only affects named parent relations in the $touches
property on the model class. Not the 'updated_at'
column.
Potential use cases
- Changing a tertiary timestamp that shouldn’t affect the overall model’s state
- A cron job or system command modifying a status when you want ‘updated_at’ to track when the user made a change, not the system.
update() replacement method
Funnily enough since Laravel 5.1 a colleague created a 100% working app-level solution that we removed in lieu of discovering the framework’s ['timestamps' => false]
option. I made reference to its closure-based implementation in a previous tap() helper discussion. Here it is restored with higher-order tap()
magic to allow chaining off the model instance.
Stick it in your app’s base model class that extends Illuminate\Database\Eloquent\Model
.
/**
* Update the model without touching the 'updated_at' timestamp.
*
* @param array $attributes
* @return $this
*/
public function updateUntouched(array $attributes)
{
try {
$timestamps = $this->timestamps;
$this->timestamps = false;
return tap($this)->update($attributes);
} finally {
$this->timestamps = $timestamps;
}
}
PullRequest::findOrFail(12617)->updateUntouched([
'takeaway' => 'Sharp tools cut sharply (now without a timestamp update.)',
]);