Description
Laravel Version
10.35.0
PHP Version
8.2.8
Database Driver & Version
MySQL 8.0.30 Ubuntu via Sail
Description
Saving a value which is cast to a date twice on the same day causes the updated_at value to be update to the second time. I would expect the updated_at to remain at the first instance as no value has changed in the model.
I'm not sure if this is a problem related to casting, parameter setting logic, saving isDirty logic, or database connection.
I believe the root of the problem is that the value is not correctly cast into a date, and instead is always treated as a datetime.
Looking at
/**
* Determine if the new and old values for a given key are equivalent.
*
* @param string $key
* @return bool
*/
public function originalIsEquivalent($key)
{
if (! array_key_exists($key, $this->original)) {
return false;
}
$attribute = Arr::get($this->attributes, $key);
$original = Arr::get($this->original, $key);
if ($attribute === $original) {
return true;
} elseif (is_null($attribute)) {
return false;
} elseif ($this->isDateAttribute($key) || $this->isDateCastableWithCustomFormat($key)) {
return $this->fromDateTime($attribute) ===
$this->fromDateTime($original);
All date casts are treated the same for isDirty purposes which may be pushing it into the array for updates despite being the same value?
Equally I'm not sure if this is all by design because I think when using a backing sqlite database which doesn't have a date type, it is still stored as the original datetime.. Which seems counterintuitive to how casts should act as otherwise what is the difference between a date and datetime cast?
Steps To Reproduce
Create a model with a property of date_column
with a date cast
$casts = [
'date_column' => 'date'
]
If we save the model with a new date_column value using $model->update(['date_column' => now()])
, the model will save and change the updated_at
to now as expected.
If then after a few seconds we save the model again $model->update(['date_column' => now()])
, the model will again be saved, and the updated_at
changed, but the column value has not changed.