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

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.)',
]);