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);
}
So with the new
AsArrayObject
andAsCollection
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
andAsCollection
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.