-
Notifications
You must be signed in to change notification settings - Fork 11.1k
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
Model::offsetExists calls getAttribute and may result in double calls #36026
Comments
We likely won't be changing this behavior on a patch release. If your accessor does computationally expensive operations - consider caching or memoizing those results. |
Yes, I can patch my code for this bug, thanks. That'snot the point. This is not a good behaviour that is likely affecting a lot of people out there. There's absolutely no reason to actually call the accessor on The implementation is unsound and should at least be considered for the next release. Closing the issue will sweep it under the carpet. |
I think there is very little potential for harm in fixing this, it would only affect users who are somehow reliant on having The implementation looks simple enough, we could try a PR and see how the test suite copes and how well that is received. Let's just target the next major version to be totally safe. |
hey @spawnia. Is there any repo that I use that you are not a maintainer? I feel I owe you a beer. Or perhaps you owe me one :D I'll post a PR tomorrow to get this started. Thanks for the support. |
I tried my hand at implementing your proposed changes in |
On a side note, I am not a maintainer of Laravel yet, although i have contributed some small stuff in the past. |
Description:
This is the current implementation of
Model::offsetExists()
:It calls
getAttribute()
, which may call actual functions as in the case of accessors. This is a problem when there's a combination of checking/getting:For normal fields this is ok, but when you have an accessor, which may not be pure, it's a problem. It may call a database, and you have a performance hit. It can generate logs or other write operations that are now doubled.
This issue is affecting users and has been reported as a side effect in other projects: webonyx/graphql-php#759 and nuwave/lighthouse#1671.
Steps To Reproduce:
Outlined above.
Fix suggestion:
I suggest a
hasAttribute
method onEloquent/Concerns/HasAttributes.php
that mirrorsgetAttribute()
but doesn't actually call anything:If you agree to it I can send a PR.
The only questionable point is the last if in
hasRelationValue()
. It assumes that the relation exists from the class data, but it may throw ongetRelationshipFromMethod()
. There seems to be no more reliable way to do it. The current implementation can throw onisset()
, while my suggestion would only throw inoffsetGet
.I consider this issue is relatively important, as it doubles operations on non-trivial model accessors for all users.
The text was updated successfully, but these errors were encountered: