I recently saw an awesome tweet while browsing twitter which introduced this idea of tappable query scopes, and wanted to share it and dig into it a little more. The idea originally came from a PR on the laravel/framework repo in the comments https://github.com/laravel/framework/pull/42111#issuecomment-1116944244.
So what we have is an invokable class that acts like a callable that we can simply call to extend the query we are building. So in effect the above example could use the below: User::query()->tap(function (Builder $query) { $query->where('email', 'taylor@laravel.com'); })->get(); But what if we want to call multiple scopes on a query?
Builder::macro('filter', function (...$scopes): Builder { collect($scopes)->each(function ($scope) { $this->tap($scope); }); return $this; }); So we are extending the Builder and adding the filter method.