Reputation: 2687
I have a simple todo application in Laravel. I have implemented global scopes to avoid that users have the ability to change todo items from other users. My global scope looks as follows:
class UserScope implements Scope
{
public function apply(Builder $builder, Model $model)
{
$builder->where('user_id', '=', Auth::id());
}
}
and in the Todo model I have the following:
class Todo extends Model { ...
protected static function booted()
{
static::addGlobalScope(new UserScope);
}
}
Routes file is:
Auth::routes();
Route::group(['middleware' => ['auth', 'verified']], function() {
Route::get('todos', 'TodosController@index')->name('todos.index');
Route::post('todos', 'TodosController@store')->name('todos.store');
Route::get('todos/create', 'TodosController@create')->name('todos.create');
Route::patch('todos/{todo}', 'TodosController@update')->name('todos.update');
Route::get('todos/{todo}', 'TodosController@show')->name('todos.show');
Route::delete('todos/{todo}', 'TodosController@destroy')->name('todos.destroy');
Route::get('todos/{todo}/edit', 'TodosController@edit')->name('todos.edit');
});
This works well and users cannot access items from someone else.
However if I have the following URLs:
I get a simple error message.
ErrorException Undefined variable: todo
Reason is that route 'blabla' does not exist. Also, the todo item '1blabla' does not exist.
I was thinking that Global Scopes would also deal with this but this is clearly not the case.
What is the best way in Laravel to define a catch all route that deals with this.
Upvotes: 0
Views: 705
Reputation: 3529
You should define a routing pattern which restricts todo
parameter. By the way, the routes won't match if the pattern doesn't.
For example, if todo
must be only numeric:
Route::pattern('todo', '\d+');
https://laravel.com/docs/7.x/routing#parameters-global-constraints
If you want a runtime check, you need a middleware which will inspect the request's route
$todo = $request->route()->param('todo');
if ($notValidTodo) {
abort(404, 'Not found todo');
}
Upvotes: 0