`Illuminate\Support\Manager::class` is an abstract class that you can inherit from to assist you in constructing your own manager implementation for your drivers. This class only requires you to implement `getDefaultDriver()` method in your own class. Creating drivers can either be by using closure, or declaring a `create{DriverName}Driver` in your manager implementation. One good example of concrete implementation is Laravel's `Illuminate\Hashing\HashManager::class`, which inherits from `Manager::class` and shows you how to manage your drivers. **P.S:** I know, I know! Code to interface not inheritance. First, you can still code to interface while inheriting from this class. Also, this is just an optional approach for creating manager classes, so it's still up to you as a developer.
Published Articles
Long controller methods and complicated queries often times go hand in hand. One of the common reasons I see is that developers don't utilize dynamic scopes for their models enough (or at all). As a rule of thumb, whenever I find 'where' query calls that needs a callback, I usually do throw that into a scope. I find this most common when I need to do some sort of constraint on the relationship. Throwing your query calls into a scope abstracts the actual implementation, and you can just re-use the scope whenever you want. ## Example: We are developing a medical service app and we are tasked to get all the doctors having cases assigned to the current authenticated doctor and include a count of cases assigned by each doctor. Our original implementation goes like this.. use App\Models\Doctor; use Illuminate\Support\Facades\Auth; ... public function index() { return Doctor::whereHas('cases', function ($query) { $query->where('assignee_id', Auth::id()); }) ->withCount(['cases' => function ($query) { $query->where('assignee_id', Auth::id()); }]) ->get(); } This implementation isn't bad at all. However, reading this takes a while to process what this code is trying to accomplish. Also, if we are going to use the scope on other places aside from the `index()` method, it makes more sense to just extract it to a scope. Let's see how we can refactor this.. use App\Models\Doctor; use Illuminate\Support\Facades\Auth; ... public function index() { return Doctor::onlyWithCasesAssignedTo(Auth::user()) ->withCountOfCasesAssignedTo(Auth::user()) ->get(); } // Then in our Doctor model, we add couple of query scopes.. use Illuminate\Database\Eloquent\Builder; ... public function scopeOnlyWithCasesAssignedTo(Builder $query, Doctor $doctor) { return $query->whereHas('cases', function ($query) { $query->where('assignee_id', $doctor->id); }); } public function scopeWithCountOfCasesAssignedTo(Builder $query, Doctor $doctor) { return $query->withCount(['cases' => function ($query) { $query->where('assignee_id', Auth::id()); }]); } And there you go! We've successfully extracted the complicated queries from our controller to their dedicated query scope methods. Cheers!
If you need a more robust reporting of your Exceptions, you can just add a report() method to your exception classes. Laravel will auto-detect that (and the render method) and run the logic inside. What's the difference between render and report in Exception classes? In render method you will typically want to return a response of some type (json/view), while report method you will typically want to Log the exception (file/database). And if you are using some 3rd party reporting tool like Sentry or Bugsnag you will want to call that in the report method as well. ``` use Exception; use Illuminate\Support\Facades\Log; class FooException extends Exception { /** * Report the exception. * * @return void */ public function report() { // Using simple Log Log::warning($this->getMessage()); // Using 3rd party integration like Sentry or Bugsnag app('sentry')->captureException($this); } } ```