laravel / ideas

Issues board used for Laravel internals discussions.
938 stars 28 forks source link

Make AsArrayObject/AsCollection support dirty detection of deep information #2532

Open tpetry opened 3 years ago

tpetry commented 3 years ago

So with the new AsArrayObject and AsCollection casts simple operations like $user->options['key'] = $value do work now as expected which is a big improvement 🚀. But a nested array/collection will not work with the new casts $user->options['key']['subkey'] = $value

This again introduces some strange behaviour. In the past you had to remember that the simple operation did not work now you have to remember that you can only change the first level of the casts directly on the Model property. With more complex arrays/collections or custom mutable data transfer objects this will still be problematic.

How about adding another interface any cast can implement which can help the eloquent dirty detection with detecting changes on any custom object. The idea would be to ask the cast whether the attribute has changed. How to calculate this is up to the cast. This could be done for the AsArrayObject and AsCollection by e.g. transforming their values to json and comparing their string representation, by using the == or === operator on the arrays or by some more complex logic.

interface CastsAttributesWithDirtyDetection extends CastsAttributes
{
    /**
     * Decide whether the attribute from the underlying model values is dirty.
     *
     * @param  \Illuminate\Database\Eloquent\Model  $model
     * @param  string  $key
     * @param  mixed  $value
     * @param  array  $attributes
     * @return bool
     */
    public function isDirty($model, string $key, $value, array $attributes);
}