-
Notifications
You must be signed in to change notification settings - Fork 11.2k
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
[5.3] Custom casting of eloquent properties #16305
Conversation
allows us to cast to non-primitives.
Is your What happens when you change it, and then save your model? With your current implementation, the record in the database will not be updated. |
I believe we should consider get and set casters. I made something related to this in my package's model class. However, I think @JosephSilber does have a point. |
Is it worth revisiting my implementation of this? #13706 |
I think so. How would #13706 work with packages? would we have to subclass to add the 2 methods? the specific package I sent this PR for was because of https://github.com/moneyphp/money unfortunately they make their |
Blah, final classes are so supersitious. :( I’ll have to think on that. |
Custom casts would mean less / no changes are necessary in core for laravel/ideas#293 |
switch ($this->getCastType($key)) { | ||
$castType = $this->getCastType($key); | ||
|
||
if (method_exists($this, 'castTo' . strtoupper($castType))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth to tweak that a bit:
if (method_exists($this, $method = 'castTo'.ucfirst(Str::camel($castType)))) {
return $this->$method($value);
}
So that 'foo_bar_baz'
type could be handled by castToFooBarBaz($value)
?
i feel like maybe we should close my PR. I feel like this may be a bigger issue that needs to be thought out, with a good plan of action. just trying to avoid having the PR sit in limbo. thoughts? |
@browner12 #16460 was another attempt on this with more control but also got closed. |
Yeah, I think this particular implementation is not going to be preferred because the modifications of the casted models do not get synced back into the model before save. My PR does not that but as noted will not work with "final" classes since they are artificially restrict developer freedom unfortunately. |
that's fine by me. thanks for closing this. hopefully we can find some solution for this. |
currently we gets dates autocast to Carbon objects, and we can cast any property to primitive types.
this PR allows us to cast properties to our own custom-defined types (usually objects i'm guessing).
Here is my use case. I have an
Order
model that hassubtotal
,tax
,shipping
, andtotal
fields. I want them all to be instances of the newMoney\Money
class, so I can work with monetary values easier. To do this I would simply set these fields in my cast property:Then I just need to define a
castToMoney()
method on the class:Now when accessing the property on the model, it would automatically give me back the
Money
object:I think the easiest way to define these 'cast methods' would be as a trait that was imported to models where it was needed. If your models extended a base class, it could also be defined there.
I wasn't able to a good test for how this behaves when the model is turned into an array (
$order->toArray()
). wondering what thoughts would be for this.I can foresee someone saying why not just define the property with an 'Accessor'. My argument would be that's fine for 1-off field manipulation, but when you are doing the same casting over and over this an easier more consistent way. If you ever need to swap out one of these 'cast methods' you can do it in one place.
Thanks for any feedback.