-
-
Notifications
You must be signed in to change notification settings - Fork 266
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
Make it possible to modify eager-loading queries by extending SelectFields #877
Make it possible to modify eager-loading queries by extending SelectFields #877
Conversation
The same $queryArgs variable was passed to every method in the class, although it was only used by validateField() method. Instead of passing the same variable as a parameter to every method, this commit simply retrieves the variable from the instance when the variable is needed.
The same $ctx variable was passed to every method in the class, although it was only used by getSelectableFieldsAndRelations() and validateField() methods. Instead of passing the same variable as a parameter to every method, this commit simply retrieves the variable from the instance when the variable is needed.
These two methods are added to make it possible to customize the behavior of eager-loading, when needed.
With this change, the custom columns added to the select statement by the custom queries are not overridden.
I've spoken out multiple times against the use of I exclusively use the dataloader approach and never use(d) Your approach might be better, make things correct, better for the future but I just need to look at a few lines of the PR and realize it's major breaking change and would require bump of a new major version; like right after I realized 8.0.0 we would need to jump to 9.0.0 alone due to this PR 😅 I'm trying to navigate the muddy waters of this part of the library and find a safe harbor and I bet you invested already more time then I ever did into it. I wonder if |
I use the selectfields approach for 95% of use cases and it makes very fast and simple to write most queries. I do agree it is a bit coupled. Crreating it own package is not a bad idea. More like a plugin is good idea. One way of decoupling/organizing it could be add all select options under one key, so instead of alias, always, is_relation being it own "root" key, we would add it to selectable, maybe also make it possible to be set as an DTO (so we validate the params are correct), or maybe transfed to DTO. So you can't set wrong values, this could of course be done with all params.
Then we could start deprecating the keys in the root. |
@mfn Sorry that I did not reply earlier. After you pointed out the data loader approach, I started checking it out and implementing it into my project. I see how it is a better approach, given that it was originated at Facebook. I actually started to move away from Apart from these, if you agree, I can make another PR that does not break backwards compatibility yet allows to override the following eager-loading function: return function ($query) use ($with, $select, $customQuery, $requestedFields, $ctx): void {
if ($customQuery) {
$query = $customQuery($requestedFields['args'], $query, $ctx) ?? $query;
}
$query->select($select);
$query->with($with);
}; Basically, moving the creation of this function to its own protected static method will do the job for me and probably many others. I am currently overriding the entire SelectFields::getSelectableFieldsAndRelations() method just to override the eager-loading function returned from that method. Overriding just the returned function would make it more maintainable. |
Hi everyone, Is there currently any progress on this? I would love to see this in the next release :) |
Not from my side currently. Working on anything |
I completely moved away from |
Hm.. too bad. I thought I could avoid to refactor our project. |
Closing this PR therefore; it can always by picked up by someone motivated 🤞🏼 |
Summary
This project is a tremendous help. However, when it comes to eagerly loading relations, I always end up in examining
SelectFields
class to figure out how to implement the functionality I want. Most of the time, I simply need to modify the eager-loading query, created inSelectFields
class, by considering the requested fields. I probably spent more than 100 hours in total trying to hack the package to implement what I need. The reason I spent this much time is becauseSelectFields
class is not extendible. For example, #510 talks about eagerly loading counts, which is not possible currently. The reason why I created this pull request is that I need to eagerly load counts as well. There are also other issues related toSelectFields
in this repository. For example, #875 mentions a need for a custom behavior. #806 wants to modify the behavior of eager-loading function. #799 was a nice attempt, which made it possible to extendSelectFields
and provide a customSelectFields
class to be used by the package, but it is not enough for many use-cases. The class is quite complex, as also stated here. The complexity of the class partially comes from using static methods too. This pull request partially addresses these issues.Here is a summary of the changes made in this pull request:
$queryArgs
and$ctx
variables. The methods that need them simply retrieve them via the getters. This reduces the complexity of the class.There are many eager-loading methods in Laravel. We might also need to customize the eager-loading behavior to use them as well. With the changes in this pull request, everybody can implement their own behavior. Below is an example of extending
SelectFields
to eagerly load counts:Switching to instance methods from static methods opens up the possibility of adding more hooks like
onBeforeModifyQuery
andonAfterModifyQuery
. In the future, I expect other pull requests that add other hooks when developers come across other use-cases.The changes I made are breaking changes for the applications that extend
SelectFields
. Other than that, this is non-breaking. I did not add any tests. The existing tests all pass. If this pull request is intended to be merged, I can add the tests with your directions. I did not updateREADME.md
because I did not see any guidance on how to extendSelectFields
.Type of change:
Checklist:
composer fix-style