-
-
Notifications
You must be signed in to change notification settings - Fork 249
Description
✏️ Describe the bug
When we use a Data object in a eloquent model cast, that field will always be marked as dirty even if nothing has changed.
Explanation
When retrieving a JSON field from the database it will result in a string {"x": "hello world"}
note the space after the colon also the order of the fields can be different. This is the behavior of MySQL. And I also saw the issue here for Postgres #496
While the behavior of json_encode
PHP results in the string {"x":"hello world"}
.
In eloquent itself there is a separated check for object
and collection
casts
https://github.com/laravel/framework/blob/12.x/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php#L2244
But this doesn't exists for custom casts, I created a PR in laravel laravel/framework#55945 to add the ability to do custom value checks to detect if an attribute is dirty or not.
I hope it will be merged or another option will be created, after that this issue could be resolved by adding something like the following to the DataEloquentCast
to fix this issue.
/**
* Compare the two values, and check if they are equal
*/
public function compare($model, string $key, $value1, $value2): bool
{
// Compare the two values loosly
return json_decode($value1) == json_decode($value2);
}
✅ Expected behavior
I would expect the $model->isDirty()
to return false if nothing has changed.
🖥️ Versions
Laravel: 12.17.0
Laravel Data: 4.15.1
PHP: 8.4.7
Database: MySQL (ver. 8.0.36)