After reading smart model binding responses, I was thinking is the missing
method giving too much responsibility to the router or not?
How does it work
In Laravel the fragment name has to match the parameter name. And that is how the model gets resolved.
// routes/web.php
Route::get('/users/{user}', [UserController::class, 'show']);
// UserController.php
public function show(User $user) {}
When the id, or another field, does not match a ModelNotFoundException
is thrown. And that results in a 404 redirect.
The missing
method allows you to override the 404 redirect with custom logic.
What made me question the responsibility
Before the feature existed you would do the route as follows.
// routes/web.php
Route::get('/users/{id}', [UserController::class, 'show']);
// UserController.php
public function show(int $id) {
$user = User::find($id);
// handle if the model is found or not
}
So this was the responsibility of the controller.
When I'm not sure about something I always go back to how I do things in Symfony.
In Symfony the resolver works slightly different. Instead of matching the fragment name with the parameter name. You can add the field name to the fragment and the resolver figures it out by the model you add as the type.
// UserController.php
#[Route('/user/{id}')]
public function show(User $user) {}
I made it a habit to use a repository method to resolve the model.
public function show(
#[MapEntity(expr: 'repository.getById(id)')]
User $user
)
Instead of throwing an exception, I return an empty entity if the id doesn't match.
That is how I keep the responsibility to redirect as a part of the controller code.
What is the verdict?
Keeping the responsibility in the controller feels like the right way of doing this.
The main concern with the Laravel way for me is that there is redirect logic in the router configuration and there can be redirect logic in the controller. So you have to check two places. While it isn't that big of a task it can slow you down if you don't know the project.
I do understand why the Laravel router has the missing
method. It is more focused on the route files. While Symfony routing is more controller based.
Top comments (0)