wiwa1978
wiwa1978

Reputation: 2687

Laravel Catch All route

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

Answers (1)

Shizzen83
Shizzen83

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

Related Questions