laravel named resources not working properly and removes the dots from the beginning - laravel

problem:
I'm trying to add name prefixes to my route groups:
Route::middleware(['auth:sanctum', 'verified'])->prefix('dashboard')->name('dashboard')->group(function () {
Route::get('', [DashboardController::class, 'dashboard']);
// other routes
Route::resource('estates', EstateController::class, ['names' => '.estates' ])->except('show');
// other routes
});
it removes the .. (it should be dashboard.estates.index , etc ...)
| POST | dashboard/estates | dashboardestates.store |
| GET|HEAD | dashboard/estates | dashboardestates.index |
| GET|HEAD | dashboard/estates/create | dashboardestates.create |
| DELETE | dashboard/estates/{estate} | dashboardestates.destroy |
| PUT|PATCH | dashboard/estates/{estate} | dashboardestates.update |
| GET|HEAD | dashboard/estates/{estate}/edit | dashboardestates.edit |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test 1:
how ever if I pass an array option to names it works fine with dots ..
Route::resource('estates', EstateController::class, ['names' => ['index' => '.estates.index'] ])->except('show');
| POST | dashboard/estates | dashboardestates.store |
| GET|HEAD | dashboard/estates | dashboard.estates.index |
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test 2:
// web.php
Route::resource('estates', EstateController::class, ['names' => '.estates.' ])->except('show');
routes list:
| POST | dashboard/estates | dashboardestates..store |
| GET|HEAD | dashboard/estates | dashboardestates..index |
| GET|HEAD | dashboard/estates/create | dashboardestates..create |
| DELETE | dashboard/estates/{estate} | dashboardestates..destroy |
| PUT|PATCH | dashboard/estates/{estate} | dashboardestates..update |
| GET|HEAD | dashboard/estates/{estate}/edit | dashboardestates..edit |
expected: dashboard.estates..index, etc
got: dashboardestates.index, etc

You can simplify it all to as follows:
Route::group(['middleware' => ['auth:sanctum', 'verified']], function () {
Route::get('/dashboard', [DashboardController::class, 'dashboard'])
->name('dashboard');
Route::group(['prefix' => '/dashboard', 'as' => 'dashboard.'], function () {
Route::resource('estates', EstateController::class)->except('show');
});
});
The output of the above for named routes will be dashboard.estates.{method}.
This could be simplified (i.e. not repeating or nesting certain things) the named route for the dashboard were to be dashboard.index rather than dashboard.

Related

Getting same page on every URL/Route in Laravel8

I'm using default laravel auth , I have multiple routes with prefix group but when I use other routes/urls but giving the same page on every route which is View page the product
you can see my route
Auth::routes();
Route::prefix('products')->group(function () {
Route::get('/', [ProductsController::class, 'index']);
Route::get('/{code}', [ProductsController::class,'view_product'])->name('products.view_product');
});
On this below route giving the product_view page which I can't understand why is giving
Route::get('/test_route', , function () {
return 'Hello World';
});
+--------+----------+--------------------------+-----------------------------+--------------------------------------------------------
----+------------------------------------------+
| Domain | Method | URI | Name | Action
| Middleware |
+--------+----------+--------------------------+-----------------------------+--------------------------------------------------------
----+------------------------------------------+
| | GET|HEAD | api/user | generated::suiIeX6oHZWSnSP1 | Closure
| api |
| | | | |
| App\Http\Middleware\Authenticate:sanctum |
| | GET|HEAD | sanctum/csrf-cookie | generated::WKOquUKjM8nfHvKl | Laravel\Sanctum\Http\Controllers\CsrfCookieController#s
how | web |
| | GET|HEAD | products | generated::IucNuoXqqYtZPi70 | App\Http\Controllers\ProductsController#index
| web | |
| | GET|HEAD | {code} | products.view_product | App\Http\Controllers\ProductsController#view_product
| web |
+--------+----------+--------------------------+-----------------------------+--------------------------------------------------------
----+------------------------------------------+

Laravel 7 Route Group return 404 on some related routes

Route::group(['prefix'=>'cart'], function (){
Route::get('', 'CartController#index')->name('cart.index');
Route::get('{id}', 'CartController#create')->name('cart.create')->middleware('auth');
Route::any('update/{id}/{qty}', 'CartController#update')->name('cart.update')->middleware('auth');
Route::any('saveorder', 'CartController#store')->name('cart.store')->middleware('auth');
Route::any('delete/{rowId}', 'CartController#destroy')->name('item.delete')->middleware('auth');
Route::any('empty', 'CartController#empty')->name('cart.empty')->middleware('auth');
});
Some of the routes still works but some of them are broken and returning 404 even that the routes exist
the broken routes are : item.delete , cart.empty , cart.store
| auth:api |
| | GET|HEAD | cart | cart.index | App\Http\Controllers\CartController#index | web |
| | GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS | cart/delete/{rowId} | item.delete | App\Http\Controllers\CartController#destroy | web |
| | | | | | auth |
| | GET|HEAD|POST|PUT|PATCH|DELETE|OPTIONS | cart/empty | cart.empty | App\Http\Controllers\CartController#empty | web |
| | | | | | auth |
| | POST | cart/saveorder | cart.store | App\Http\Controllers\CartController#store | web |
| | | | | | auth |
| | PUT | cart/update/{id}/{qty} | cart.update | App\Http\Controllers\CartController#update | web |
| | | | | | auth |
| | GET|HEAD | cart/{id} | cart.create | App\Http\Controllers\CartController#create | web |
| | | | |
if you're using a GET method with cart.empty and cart.store then they will be handled by cart.create, you should put those routes first (order matters), also its better to be explicit with the route methods instead of using Route::any
Route::prefix('cart')->group(function () {
Route::get('', 'CartController#index')->name('cart.index');
Route::any('saveorder', 'CartController#store')->name('cart.store');
Route::any('empty', 'CartController#empty')->name('cart.empty');
Route::any('delete/{rowId}', 'CartController#destroy')->name('item.delete');
Route::any('update/{id}/{qty}', 'CartController#update')->name('cart.update');
Route::get('{id}', 'CartController#create')->name('cart.create');
});
Route::group(['prefix' => 'cart', 'middleware' => ['auth']], function(){
Route::get('/', 'CartController#index')->name('cart.index');
Route::get('/{id}', 'CartController#create')->name('cart.create');
Route::any('/update/{id}/{qty}', 'CartController#update')->name('cart.update');
Route::any('/saveorder', 'CartController#store')->name('cart.store');
Route::any('/delete/{rowId}', 'CartController#destroy')->name('item.delete');
Route::any('/empty', 'CartController#empty')->name('cart.empty');
});
Route::prefix('cart')->group(function (){
Route::middleware(['auth'])->group(function(){
Route::get('{id}', 'CartController#create')->name('cart.create');
Route::put('update/{id}/{qty}', 'CartController#update')->name('cart.update');
Route::post('saveorder', 'CartController#store')->name('cart.store');
Route::delete('delete/{rowId}', 'CartController#destroy')->name('item.delete');
Route::post('empty', 'CartController#empty')->name('cart.empty');
});
Route::get('/', 'CartController#index')->name('cart.index');
});
Two things to consider. Your cart.index could potentially match URI's underneath the route. For security, please try not to use Route::any if possible. As explained in https://laravel.com/docs/7.x/routing. As #Sobir suggests, run php artisan route:list and see your actual list of routes as Laravel sees it.
If something is missing or ambiguous, you may have to reconsider some route parameters to avoid confusion. Or regroup them in different ways. Your route list will certainly grow. Anticipate on what you're planning in the future of what you are building.

route names inside a group prefix does not include the prefix

I have these routes:
Route::group(['middleware' => ['role:admin'], 'prefix' => 'admin'], function()
{
Route::resource(__('route.events'), 'Auth\RoleAdmin\EventController');
});
Route::group(['middleware' => ['role:user'], 'prefix' => 'user'], function()
{
Route::resource(__('route.events'), 'Auth\RoleUser\EventController');
});
I would expect the name of the resources routes start with admin. and user. respectively, but it does not happen.
This is the result of the command php artisan route:list:
| | GET|HEAD | auth/admin/events | events.index | App\Http\Controllers\Auth\RoleAdmin\EventController#index | web,auth,role
:admin,guest,role:admin|user |
| | POST | auth/admin/events | events.store | App\Http\Controllers\Auth\RoleAdmin\EventController#store | web,auth,role
:admin,guest,role:admin|user |
| | GET|HEAD | auth/admin/events/create | events.create | App\Http\Controllers\Auth\RoleAdmin\EventController#create | web,auth,role
:admin,guest,role:admin|user |
| | DELETE | auth/admin/events/{events} | events.destroy | App\Http\Controllers\Auth\RoleAdmin\EventController#destroy | web,auth,role
:admin,guest,role:admin|user |
| | GET|HEAD | auth/admin/events/{events} | events.show | App\Http\Controllers\Auth\RoleAdmin\EventController#show | web,auth,role
:admin,guest,role:admin|user |
| | PUT|PATCH | auth/admin/events/{events} | events.update | App\Http\Controllers\Auth\RoleAdmin\EventController#update | web,auth,role
:admin,guest,role:admin|user |
| | GET|HEAD | auth/admin/events/{events}/edit | events.edit | App\Http\Controllers\Auth\RoleAdmin\EventController#edit | web,auth,role
:admin,guest,role:admin|user |
As you can see the routes of admin and routes of users have the same names, and the names don't include the prefix.
The kerbholz's solution is not working, but it helped me to solve.
Route::prefix('admin')
->middleware('role:admin')
->name('admin.') // <-- I had to add this line in order to work
->group(function() {
Route::resource(__('route.events'), 'Auth\RoleAdmin\EventController');
});
Change your routes to have prefix and middleware outside of the group:
Route::prefix('admin')
->middleware('role:admin')
->group(function() {
Route::resource(__('route.events'), 'Auth\RoleAdmin\EventController');
});
Route::prefix('user')
->middleware('role:user')
->group(function() {
Route::resource(__('route.events'), 'Auth\RoleUser\EventController');
});
https://laravel.com/docs/6.x/routing#route-groups

Insert variable into named route using Redirect::route()

I am trying to redirect a route to a named router that contains a variable. Somehow the URL gets resolved into http://localhost:8000/users/reset_password?token=f3c6e64d3d5147fde8843af831ca4998 instead of http://localhost:8000/users/reset_password/f3c6e64d3d5147fde8843af831ca4998 (mind the ?token=)
Because of this mismatch in the URL that gets created, the incorrect route is used.
The Redirect::route() code looks like this:
return Redirect::route('users.reset', array('token'=>$input['token']))
->withInput()
->with('error', $error_msg);
My routes are defined as follows:
Route::get('users/confirm/{code}', array('as' => 'users.confirm', 'uses' => 'UsersController#getConfirm'));
Route::get('users/forgot_password', array('as' => 'users.forgot', 'uses' => 'UsersController#getForgot'));
Route::post('users/forgot_password', array('as' => 'users.forgot', 'uses' => 'UsersController#postForgot'));
Route::get('users/reset_password/{token}', array('as' => 'users.reset', 'uses' => 'UsersController#getReset'));
Route::post('users/reset_password', array('as' => 'users.reset', 'uses' => 'UsersController#postReset'));
Route::resource('users', 'UsersController');
The command php artisan routes gives the next output:
+--------+---------------------------------------+------------------+----------------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+---------------------------------------+------------------+----------------------------------+----------------+---------------+
| | GET|HEAD users/confirm/{code} | users.confirm | UsersController#getConfirm | | |
| | GET|HEAD users/forgot_password | users.forgot | UsersController#getForgot | | |
| | POST users/forgot_password | users.forgot | UsersController#postForgot | | |
| | GET|HEAD users/reset_password/{token} | users.reset | UsersController#getReset | | |
| | POST users/reset_password | users.reset | UsersController#postReset | | |
| | GET|HEAD users | users.index | UsersController#index | | |
| | GET|HEAD users/create | users.create | UsersController#create | | |
| | POST users | users.store | UsersController#store | | |
| | GET|HEAD users/{users} | users.show | UsersController#show | | |
| | GET|HEAD users/{users}/edit | users.edit | UsersController#edit | | |
| | PUT users/{users} | users.update | UsersController#update | | |
| | PATCH users/{users} | | UsersController#update | | |
| | DELETE users/{users} | users.destroy | UsersController#destroy | | |
+--------+---------------------------------------+------------------+----------------------------------+----------------+---------------+
The problem is you have two routes defined with the same name. Either your POST and GET routes have the same users.reset name. And the second one is overwriting the first. Change your name for POST route and you will be fine.
I think the problem is that you also define the name of the variable, you only need to define the variables itself in the correct order:
Redirect::route('users.reset', array($input['token'])
->withInput()
->with('error', $error_msg);

Naming of grouped resource route

I have the below route group with a resource inside.
Route::group(array( 'prefix' => 'admin' , 'before' => 'admin-auth' ), function() {
Route::group(array( 'prefix' => 'hosts'), function() {
Route::resource('/', 'HostsController' );
});
});
As I've seen in the php artisan routes
| GET /admin/hosts | admin.hosts...index | HostsController#index | admin-auth
| GET /admin/hosts/create | admin.hosts...create | HostsController#create | admin-auth
| POST /admin/hosts | admin.hosts...store | HostsController#store | admin-auth
| GET /admin/hosts/{} | admin.hosts...show | HostsController#show | admin-auth
| GET /admin/hosts/{}/edit | admin.hosts...edit | HostsController#edit | admin-auth
| PUT /admin/hosts/{} | admin.hosts...update | HostsController#update | admin-auth
| PATCH /admin/hosts/{} | | HostsController#update | admin-auth
| DELETE /admin/hosts/{} | admin.hosts...destroy | HostsController#destroy | admin-auth
How can I call the link to the route?
I've tried something like
{{route('admin.hosts...show', array($host->id) )}}
But I get a array_combine() error.
Edit
I've changed to this.
Route::group(array( 'prefix' => 'admin' , 'before' => 'admin-auth' ), function() {
Route::resource('/hosts', 'HostsController' );
but still I get a double dotted route name.
GET /admin/hosts | admin..hosts.index | HostsController#index
GET /admin/hosts/create | admin..hosts.create | HostsController#create
POST /admin/hosts | admin..hosts.store | HostsController#store
GET /admin/hosts/{hosts} | admin..hosts.show | HostsController#show
GET /admin/hosts/{hosts}/edit | admin..hosts.edit | HostsController#edit
PUT /admin/hosts/{hosts} | admin..hosts.update | HostsController#update
PATCH /admin/hosts/{hosts} | | HostsController#update
DELETE /admin/hosts/{hosts} | admin..hosts.destroy | HostsController#destroy
Now I can make it work but isn't it kind of weird?
You hosts is your /, then you don't need a new group for your resources:
Route::group(array( 'prefix' => 'admin' , 'before' => 'admin-auth' ), function() {
Route::resource('hosts', 'UsersController' );
});
And you'll get something like this:
+--------+-----------------------------------------------------+-------------------------------------------+-------------------------------------------------+----------------------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+-----------------------------------------------------+-------------------------------------------+-------------------------------------------------+----------------------------+---------------+
| | GET admin/hosts | admin.hosts.index | UsersController#index | admin-auth | |
| | GET admin/hosts/create | admin.hosts.create | UsersController#create | admin-auth | |
| | POST admin/hosts | admin.hosts.store | UsersController#store | admin-auth | |
| | GET admin/hosts/{hosts} | admin.hosts.show | UsersController#show | admin-auth | |
| | GET admin/hosts/{hosts}/edit | admin.hosts.edit | UsersController#edit | admin-auth | |
| | PUT admin/hosts/{hosts} | admin.hosts.update | UsersController#update | admin-auth | |
EDIT
Also, this is the right route:
Route::resource('hosts', 'UsersController' );
Not this one:
Route::resource('/hosts', 'UsersController' );

Resources