Post-Process Query Results Elegantly with Laravel's afterQuery Method
Last updated on by Harris Raftopoulos

Enhance your Eloquent query handling with Laravel's new afterQuery() hook, which provides a streamlined approach to manipulating collections after database retrieval while keeping your codebase cleaner and more maintainable.
$query->afterQuery(function ($models) { // Make changes to the queried models ...});
This powerful method accepts a closure that receives the collection of models returned by your query, enabling you to perform transformations, add computed properties, or apply other modifications directly to the results before they're returned to your application code.
// Beforepublic function scopeWithIsFavoriteOf($query, ?User $user = null) : void{ if ($user === null) { return $query; } $query->addSelect([ // 'is_favorite' => some query ... ]);} $products = Product::withIsFavoriteOf(auth()->user())->get(); if (auth()->user() === null) { $products->each->setAttribute('is_favorite', false);}
The traditional approach above requires checking for a null user in two separate places - once in the scope definition and again after executing the query. This creates a brittle relationship where your controller code must understand and implement additional processing based on authentication state.
// Afterpublic function scopeWithIsFavoriteOf($query, ?User $user = null) : void{ if ($user === null) { $query->afterQuery(fn ($products) => $products->each->setAttribute('is_favorite', false)); return; } $query->addSelect([ // 'is_favorite' => some query ... ]);} Product::withIsFavoriteOf(auth()->user())->get();
With afterQuery(), the responsibility for handling the null user case remains entirely encapsulated within the scope. Your controller code simply calls the scope without needing to know about or implement conditional logic, resulting in more robust and maintainable application design.