Jimmy Zoto
Jimmy Zoto

Reputation: 1763

Laravel 5 Route::resource inside nested Route::group

This structure works for (all GET) : /dashboard/video, /dashboard/video/element, /dashboard/video/create,/dashboard/video/element/create, /dashboard/video/element/{id}, but not for /dashboard/video/{id}.

In other words, show($id) isn't getting called for /dashboard/video/{id}.

Any idea why?

Route::group(['prefix' => 'dashboard', 'middleware' => ['csrf', 'auth']], function () {

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

        // non-standard delete: sends array of ids in request body
        Route::delete('/', 'InteractiveVideoController@destroyMany');
        Route::resource('/', 'InteractiveVideoController');

        Route::resource('element', 'InteractiveElementController');
    });
...
});

Upvotes: 2

Views: 2722

Answers (1)

Sh1d0w
Sh1d0w

Reputation: 9520

The problem can become easily visible when you execute

php artisan route:list

From the generated table you can see this:

|        | GET|HEAD                       | dashboard/video                                       | dashboard.video..index   | App\Http\Controllers\InteractiveVideoController@index      |            |
|        | GET|HEAD                       | dashboard/video/create                                | dashboard.video..create  | App\Http\Controllers\InteractiveVideoController@create     |            |
|        | POST                           | dashboard/video                                       | dashboard.video..store   | App\Http\Controllers\InteractiveVideoController@store      |            |
|        | GET|HEAD                       | dashboard/video/{}                                    | dashboard.video..show    | App\Http\Controllers\InteractiveVideoController@show       |            |
|        | GET|HEAD                       | dashboard/video/{}/edit                               | dashboard.video..edit    | App\Http\Controllers\InteractiveVideoController@edit       |            |
|        | PUT                            | dashboard/video/{}                                    | dashboard.video..update  | App\Http\Controllers\InteractiveVideoController@update     |            |
|        | PATCH                          | dashboard/video/{}                                    |                          | App\Http\Controllers\InteractiveVideoController@update     |            |
|        | DELETE                         | dashboard/video/{}                                    | dashboard.video..destroy | App\Http\Controllers\InteractiveVideoController@destroy    |            |

As you can see by defining the videos route as / under videos group will not work, simply because in order the resource controller to create restful paths with parameters, it uses the first part of the path as variable name. In your case it is empty (just a slash / that gets stripped), that's why you get this {}.

You have to change your routes.php and move the videos resource out of the group and it will work, like this:

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

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

        Route::resource('element', 'InteractiveElementController');
    });

    // non-standard delete: sends array of ids in request body
    Route::delete('video', 'InteractiveVideoController@destroyMany');
    Route::resource('video', 'InteractiveVideoController');

});

You have to put video resource under video element, otherwise video/element will never match, since the order of the routes that are defined matters.

This will work for you and now all pages will open normally. You can also check that the routes are defined correctly by executing again:

php artisan route:list

|        | GET|HEAD                       | dashboard/video                                       | dashboard.video.index   | App\Http\Controllers\InteractiveVideoController@index      |            |
|        | GET|HEAD                       | dashboard/video/create                                | dashboard.video.create  | App\Http\Controllers\InteractiveVideoController@create     |            |
|        | POST                           | dashboard/video                                       | dashboard.video.store   | App\Http\Controllers\InteractiveVideoController@store      |            |
|        | GET|HEAD                       | dashboard/video/{video}                                    | dashboard.video.show    | App\Http\Controllers\InteractiveVideoController@show       |            |
|        | GET|HEAD                       | dashboard/video/{video}/edit                               | dashboard.video.edit    | App\Http\Controllers\InteractiveVideoController@edit       |            |
|        | PUT                            | dashboard/video/{video}                                    | dashboard.video.update  | App\Http\Controllers\InteractiveVideoController@update     |            |
|        | PATCH                          | dashboard/video/{video}                                    |                          | App\Http\Controllers\InteractiveVideoController@update     |            |
|        | DELETE                         | dashboard/video/{video}                                    | dashboard.video.destroy | App\Http\Controllers\InteractiveVideoController@destroy    |            |

Upvotes: 5

Related Questions