-
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
[11.x] afterQuery
hook
#50587
[11.x] afterQuery
hook
#50587
Conversation
There are some situations where I am curious if this would take affect, which may lead to inconsistency if it doesn't. Namely, |
I added support for those relationships. The other relationship types call the |
@gdebrauwer what do you think about |
@taylorotwell I added support for those methods. I also added some extra tests to cover the change you made to the |
@gdebrauwer I'm not totally sure about the |
@taylorotwell I added support for filtering when using a cursor |
Thanks 👍 |
Tests are failing on SQL Server. |
@hafezdivandari fixed, thanks |
Old version of Laravel does not have `afterQuery` method See more: laravel/framework#50587
Explanation
Query scopes (or custom query builder methods) can be used to add constraints to a query, but in my projects, I use them a lot to hide (complex) code to add extra data to every queried model. Most of the time that code can completely live inside a scope, but there are some cases where some extra code needs to be executed after running the query. That extra code currently needs to live outside of the scope. That also means you have to remember to add that extra code after every query that uses that scope. Would it not be nice if we could keep that code in the scope itself? That is what this PR makes possible by adding an
afterQuery
method.Use cases
Set attributes or relations in certain situations
Let's say that you have a
withIsFavorite()
scope that queries a boolean attribute on every model based on the authenticated user. But if there is no authenticated user, then that boolean should just be false on every model. Using theafterQuery()
method, you can easily set that attribute on every model if there is no authenticated user.The example above could probably be done inside a query as well, but in the next example that would not be possible. Let's say we want to load the event booking of the authenticated user on every event, but if there is no authenticated user, we want to set the relation to
null
. We can easily achieve this with theafterQuery()
methodMake changes to data after it has been queried
Another example is when you load some extra data / some special relationshp in your query, but when the models are hydrated, you need to make some changes to the models and their releationships. Again, the
afterQuery()
makes it possible to keep that code together.Only load data on the queried models instead of querying that data immediately
Another use case is where you want to load some data through a subselect on a paginated query, but you only want to do that after you have fetched the models of the current page to keep the pagination query performant. You could achieve this by creating a custom eloquent collection class for that model and adding that code to a method in that custom collection class, but that is a lot of extra code and an extra class that you might not need for anything else. The
afterQuery()
method makes that a lot simpler.