Garet's avatar
Level 3

Custom route model binding, good or bad?

Currently, people can access a resource, let's call it Entity, via the following route:

Route::get('/entity/{entity}', 'EntityController@view');

I can then type hint \App\Entity on my controller to automatically retrieve the Entity requested in the URL.

Now let's say I want an authenticated user to be able to edit only their own Entity, so I have the following route:

Route::middleware('auth')->group(function () {
    Route::get('/{id}/edit', 'EntityController@edit');
}

Then my controller looks like this:

public function edit($id)
{
    $entity = Auth::user()->entities()->where('id', $id)->firstOrFail();
    ...
}

However, I need that first line of code in every controller method that needs to check the Entity belongs to the currently authenticated user (i.e. update, delete, etc).

I discovered I could create custom route model binding like so:

    Route::bind('entity_user', function($value)
    {
        return Auth::user()->entities()->where('id', $value)->firstOrFail();
    });

Then my route would look like this:

Route::middleware('auth')->group(function () {
    Route::get('/{entity_user}/edit', 'EntityController@edit');
}

And my controller methods would be simplified:

public function edit(Entity $entity)
{
    ...
}

Whilst this is a lot cleaner, I'm wondering if it's more difficult to understand from glancing at the code. Furthermore, if anyone ever edited the routes and changed entity_user to entity then it would have disastrous consequences, because all users would suddenly be able to edit Entities which don't belong to them.

So I'm wondering which is the "best" way?

0 likes
3 replies
ftiersch's avatar
ftiersch
Best Answer
Level 28

I would say that is a case for policies. So you create an EntityPolicy and determine, that a user can only view his own entities.

Then the result would be a 403 (which makes more sense too since the URL exists but the user is not allowed to access it).

topvillas's avatar

It sounds you like you need some middleware to control who can edit what.

This looks like a pretty common use case though so there might be something out there already.

Garet's avatar
Level 3

Thanks both, Policies and Middleware is what I was missing, back to school for me!

Please or to participate in this conversation.