BadMethodCallException Method [show] does not exist. Laravel

3

I have been doing a CRUD in Laravel and you are giving me an error that can not be found since I do not have any function that is called Show .

Userscontroller:

    public function destroy($id_usuario)
{
    $user = Usuario::find($id_usuario);
    $user->delete();

    Flash::warning('Se ha eliminado ' .$user->nombre . 'de forma correcta');
    return redirect()->route('users.index');
}

Index.blade.php

<a href="{{ route('users.destroy', $user->id_usuario) }}" class="btn btn-warning"><span class="glyphicon glyphicon-remove-circle" aria-hidden="true" onclick="return confirm('¿Seguro que quieres borrarlo')"></span></a>

Web.php

Route::group(['prefix' => 'admin'], function(){

Route::resource('users','Userscontroller');
Route::get('users/{id_usuario}/destroy', [
    'uses' => 'UsersController@destroy',
    'as'   => 'admin.users.destroy'
  ]);

});
    
asked by Alberto Cepero de Andrés 31.08.2017 в 13:09
source

1 answer

3

When you use Route::resource() you are creating seven routes to that controller:

'index', 'create', 'store', 'show', 'edit', 'update', 'destroy'

Each of these methods uses a specific verb and a method in the controller, as the documentation example shows in PhotoController .

Verbo       URI                     Método  Nombre de la rta
GET         /photos                 index   photos.index
GET         /photos/create          create  photos.create
POST        /photos                 store   photos.store
GET         /photos/{photo}         show    photos.show
GET         /photos/{photo}/edit    edit    photos.edit
PUT/PATCH   /photos/{photo}         update  photos.update
DELETE      /photos/{photo}         destroy photos.destroy

What happens in this case is that by clicking on the link with path users/{id_usuario}/destroy and verb GET, Laravel is finding the route of show /users/{id_usuario} generated by Route::resource() before the other one you created.

Why does this happen? The routes in Laravel are read in "order" from top to bottom, and by finding a verb match and if the "partial" or full parameter matches the route, you will use it.

In other words, when you click on the link, Laravel checks GET and then finds a match in the route that calls the show method thanks to users/{id_usuario} , and the rest of the route ( .../destroy ) is ignored.

SOLUTIONS:

  • Use the DELETE verb when doing a destroy as suggested by Laravel, for this you would call the link with a form, something like this:

    {!! Form::open(['route' => ['users.destroy', $user->id_usuario], 'method' => 'DELETE']) !!}
      {!! Form::submit('Eliminar') !!}
    {!! Form::close() !!}
    
  • Change the order of the routes so that Laravel finds your route first than the resource route:

    Route::get('users/{id_usuario}/destroy', [
        'uses' => 'UsersController@destroy',
        'as'   => 'admin.users.destroy'
    ]);
    Route::resource('users','Userscontroller');
    
  • Tell Laravel that he does not generate the route that the show method uses:

    Route::resource('users','Userscontroller', ['except' => ['destroy', 'show']]);
    
  • More information in the documentation: link

        
    answered by 31.08.2017 / 14:20
    source