Search code examples
laravel-routinglaravel-8

Laravel Route::group[] not working correctly


I have routes that I would like to group by name, prefix, and middleware together. For some reason, the 'name' option of the Route::group function is not trailing names correctly. Is my code incorrect, or is this a bug? Below is the route group definition.

Route::group(['name' => 'admin.', 'prefix' => 'admin',
    'middleware' => 'admin'], function () {
    Route::get('/', function () {
        return 'the index page';
    })->name('index');

    Route::get('/another', function () {
        return 'another page';
    })->name('another');
});

Then I cleared and cached the routes. Here's the list.

+--------+----------+------------------------+-----------------------------+------------------------------------------------------------------------+------------+
| Domain | Method   | URI                    | Name                        | Action                                                                 | Middleware |
+--------+----------+------------------------+-----------------------------+------------------------------------------------------------------------+------------+
|        | GET|HEAD | admin                  | index                       | Closure                                                                | web        |
|        |          |                        |                             |                                                                        | admin      |
|        | GET|HEAD | admin/another          | another                     | Closure                                                                | web        |
|        |          |                        |                             |                                                                        | admin      |

I am expecting to see in names admin.index, admin.another,...

However, if I use the Route::name function, it will work correctly.

Route::name('admin.')->group(function () {
    Route::prefix('admin')->group(function () {
        Route::middleware('admin')->group(function () {
            Route::get('/', function () {
                return 'the index page';
            })->name('index');

            Route::get('/another', function () {
                return 'another page';
            })->name('another');
        });
    });
});

+--------+----------+------------------------+-----------------------------+------------------------------------------------------------------------+---------------+
| Domain | Method   | URI                    | Name                        | Action                                                                 | Middleware    |
+--------+----------+------------------------+-----------------------------+------------------------------------------------------------------------+---------------+
|        | GET|HEAD | admin                  | admin.index                 | Closure                                                                | web           |
|        |          |                        |                             |                                                                        | admin         |
|        | GET|HEAD | admin/another          | admin.another               | Closure                                                                | web           |
|        |          |                        |                             |                                                                        | administrator |

Solution

  • You should replace name array entry with as like this:

    Route::group(['as' => 'admin.', 'prefix' => 'admin',
        'middleware' => 'admin'], function () {
        Route::get('/', function () {
            return 'the index page';
        })->name('index');
    
        Route::get('/another', function () {
            return 'another page';
        })->name('another');
    });
    

    However I believe your second approach is more readable. But remember that there is no need to define a group method for each property and you can simply chain all methods and define single group method at the end:

    Route::name('admin.')
        ->prefix('admin')
        ->middleware('admin')
        ->group(function () {
            Route::get('/', function () {
                return 'the index page';
            })->name('index');
    
            Route::get('/another', function () {
                return 'another page';
            })->name('another');
        });