-
Notifications
You must be signed in to change notification settings - Fork 11.4k
[5.5] Added custom attribute types #21419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
How is the reverse casting handled, when the values (the string) needs to be written back to the database (the binary array)? |
Thanks @sisve - good point. I'll add that in to. |
See @sisve's comment. Not fleshed out and is actually very complicated to do in a proper way IMO. |
@therocis @taylorotwell maybe it should be done in a very similar style like we have custom validation rules in Laravel 5.5 already? In this case we would need to introduce This is on how the model could look like: use App\Casts\MoneyCast;
class Order extends Model
{
protected $casts = [
'money' => new MoneyCast
];
} This is on how the custom cast definition could look like: use Illuminate\Database\Eloquent\Cast;
class MoneyCast implements Cast
{
public function fromDatabase($value)
{
// should return casted value (string, object, etc..)
}
public function toDatabase($object)
{
// should reverse-transform value / object back to the string that needs to be stored in the database
}
} This would defintely introduce a lot of flexibility and re-use across different models too. |
There has been some development/research into this area earlier; look into #18229 and if you want to continue on that approach. |
@sisve @taylorotwell Another possible implementation that could work is having a CastingManager in the same way the Notification system has a ChannelManager. Something like
This allows package developers to hook into the casting and extend with their own by A lot of the previous discussions on this feature in #13706 has been around mutability and caching which divides people a lot. People then argue to just use getters and setters leaving the models to have 2*n functions with duplicated logic.
Finally the object itself are not aware of Eloquent which has been another pain point discussed. There are no more coupling to your model and 'risk' of referencing relations than what would otherwise have been going on in the getter and setter. Wouldn't this be a treat for 5.6 ? :-) |
For those that may be interested, I've developed https://github.com/hnhdigital-os/laravel-model-schema which provides the mechanism for custom attribute types. The package does a bit more, such as grouping everything into a protected schema property and adding the ability to set per attribute, an auth checking method (per attribute, or a callable method to check). The way it's implemented, it continued to provide the properties that are expected. I have 73% tested at time of writing and hope to get to 100% shortly (only L5.5, but will play with 5.6 shortly). @rasmuscnielsen Your example was actually my first test of the custom type. I've implemented a Money\Money casting. I'll be implementing a JSON upgrade to do a similar thing. |
For the ability to create custom cast mutators.
In 5.5, a lot of model functionality was transferred to concerns (traits) removing the ability to override various methods in other traits.
This feature provides the ability to override existing casts built-in to Laravel, or define your own using similar naming convention used elsewhere in Laravel.
For example, we have a UUID attribute that is stored as binary in the database. When we use this value though, we need it cast as a string. Currently we would have do this with a defined mutator on each model.
This update would allow us to define a mutator in a trait that we apply to models that have this field. We would create a
castUuidValue
method which takes a value, mutates, and returns the value. In the UUID case we would convert the binary value into a string.In my personal cases, I use packages for both UUID and JSON cast types which no longer work in 5.5 due to the method collision from the new traits.