One of our apps has a simple gate that lets a user choose a client, but only if they have access to multiple clients.
The gate gets called multiple times in each request, so I wanted to reduce the number of DB queries.
Caching would be a common solution here, but then you have some additional complexity managing cache invalidation. In this case, instead of using a cache, I used a simple static variable inside my gate closure.
It looks like this:
Gate::define('choose-clients', function (User $user) {
static $clientCount = null;
if ($clientCount === null){
$clientCount = Client::forUser($user)->count();
}
return $clientCount > 1;
});
This isn't some amazing new concept, but I thought it was worth sharing as it highlights two principles:
- Don't introduce complexity (cache invalidation) until you absolutely need to.
- Don't always look for a Laravel feature, there's plenty PHP can do.
Just be aware: If you use Laravel Octane (or similar tools), this approach will not work correctly, because it shares state across requests from different users. In that case, caching is a better solution.
Here to help,
Joel
P.S. Is part of your app slower than you'd like? We can help!