I have a resourceful route called 'pages', with a PagesController and a Page model. I want the show method to be available at http://site.dev/slug instead of http://site.dev/pages/slug. How can I do this in Laravel 5?
I have tried
Route::resource('/{slug}', 'PagesController');
But that results in the following route list:
| | POST | {slug} | {slug}.store | App\Http\Controllers\PagesController#store | |
| | GET|HEAD | {slug} | {slug}.index | App\Http\Controllers\PagesController#index | |
| | GET|HEAD | {slug}/create | {slug}.create | App\Http\Controllers\PagesController#create | |
| | GET|HEAD | {slug}/{{slug}} | {slug}.show | App\Http\Controllers\PagesController#show | |
| | PUT | {slug}/{{slug}} | {slug}.update | App\Http\Controllers\PagesController#update | |
| | PATCH | {slug}/{{slug}} | | App\Http\Controllers\PagesController#update | |
| | DELETE | {slug}/{{slug}} | {slug}.destroy | App\Http\Controllers\PagesController#destroy | |
| | GET|HEAD | {slug}/{{slug}}/edit | {slug}.edit | App\Http\Controllers\PagesController#edit | |
And the show method returns the error
"Route pattern "/{slug}/{{slug}}" cannot reference variable name "slug" more than once."
When you use Route::resource('/{slug}', 'PagesController'); it will attempt to create multiple routes to handle a variety of RESTful actions. Some of those deal with individual objects referred to by an ID. For instance, the "show" method assumes "slug" to be the noun describing a group of objects and then expects an ID to identify a specific one.
I believe you can address this by using an optional route parameter for that ID and choose whether to handle it in your controller methods: Route::resource('/{slug}/{id?}', 'PagesController');
Create resource route similar to '/{slug}'.
Route::resource('/{slug}', 'MainController');
Related
I am using Laravel 5.4 and I have created a controller with resources. Now I would like to open the edit page in my app like the following:
a href="{{ route('tasks.edit', ['tasks'=>$storedTask->id]) }}" class='btn btn-default'>Edit</a>
In my view I am using:
Route::resource('/', 'IndexController');
However, I get back
Sorry, the page you are looking for could not be found when opening the link.
When looking into my routes list the URIs are emtpy.
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | / | index | App\Http\Controllers\IndexController#index | web |
| | POST | / | store | App\Http\Controllers\IndexController#store | web |
| | PUT|PATCH | {} | update | App\Http\Controllers\IndexController#update | web |
| | DELETE | {} | destroy | App\Http\Controllers\IndexController#destroy | web |
| | GET|HEAD | {} | show | App\Http\Controllers\IndexController#show | web |
| | GET|HEAD | {}/edit | edit | App\Http\Controllers\IndexController#edit | web |
+--------+-----------+------------------------+------------------+------------------------------------------------------------------------+--------------+
I guess that my model is not "associated" with my controller and therefore the Route::resource view.
Any suggestions how to fix this?
You can't use resource route with just /. Change it to:
Route::resource('tasks', 'IndexController');
When using RESTful resource controllers, we can use route::resource() to work with, but the URIs seem to be default.
+--------+-----------+--------------------+---------------+---------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+--------------------+---------------+---------------------------------------------+------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | items | items.index | App\Http\Controllers\ItemController#index | web |
| | POST | items | items.store | App\Http\Controllers\ItemController#store | web |
| | GET|HEAD | items/create | items.create | App\Http\Controllers\ItemController#create | web |
| | GET|HEAD | items/{items} | items.show | App\Http\Controllers\ItemController#show | web |
| | PUT|PATCH | items/{items} | items.update | App\Http\Controllers\ItemController#update | web |
| | DELETE | items/{items} | items.destroy | App\Http\Controllers\ItemController#destroy | web |
| | GET|HEAD | items/{items}/edit | items.edit | App\Http\Controllers\ItemController#edit | web |
| | POST | register | signup | App\Http\Controllers\UserController#SignUp | web |
| | GET|HEAD | signup | | Closure | web |
+--------+-----------+--------------------+---------------+---------------------------------------------+------------+
(ignore the first and the last two, we're looking at the 'items.something' routes)
I want to, for example, change "items/create" to "items/new".
On a previous question, the answer was "No", but since the question is over one year old and Laravel developments seems to be pretty fast, is there already a solution?
The answer hasn't really changed. You can't customize a resource controller action directly. There is a workaround however: you can exclude it and add it yourself.
First make your resource route partial and exclude the action(s) you don't want:
https://laravel.com/docs/5.2/controllers#restful-partial-resource-routes
Route::resource('items', 'ItemController', ['except' => [
'create'
]]);
Then you can add your own routes in addition:
https://laravel.com/docs/5.2/controllers#restful-supplementing-resource-controllers
Route::get('items/new', 'ItemController#new');
Make sure to stick that before the resource route, as mentioned in the docs.
Note you can customize the route name, as mentioned in that previous thread you linked to.
I created a controller named CatController with php artisan make:controller CatController. So it generated the next route list:*-> What generated the route list is on routes.php Route::resource('cat','CatsController');
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-------------------+-------------+-------------------------------------------------+------------+
| | GET|HEAD | / | | Furbook\Http\Controllers\CatController#index | |
| | GET|HEAD | cat | cat.index | Furbook\Http\Controllers\CatController#index | |
| | POST | cat | cat.store | Furbook\Http\Controllers\CatController#store | |
| | GET|HEAD | cat/create | cat.create | Furbook\Http\Controllers\CatController#create | |
| | DELETE | cat/{cat} | cat.destroy | Furbook\Http\Controllers\CatController#destroy | |
| | PATCH | cat/{cat} | | Furbook\Http\Controllers\CatController#update | |
| | PUT | cat/{cat} | cat.update | Furbook\Http\Controllers\CatController#update | |
| | GET|HEAD | cat/{cat} | cat.show | Furbook\Http\Controllers\CatController#show | |
| | GET|HEAD | cat/{cat}/edit | cat.edit | Furbook\Http\Controllers\CatController#edit | |
Later on I thought it would be better to call it CatsController and handle the urls as cats/... so I renamed the controller but I still have the same default REST actions URIs.
Is there anyway to change it? How should I proceed?
To my knowledge the make:controller command only generates the controller file, not any route definitions. The routes defined there look like they've beed generated by a Route::resource definition that would look like this:
Route::resource('cat', 'CatController');
To make that work with cats and CatsControllers you should change it to this:
Route::resource('cats', 'CatsController');
You can read more on RESTful Resource Controllers in the Laravel Documentation.
I have the following Route defined:
Route::resource('profile', 'ProfileController', ['except' => ['create', 'destroy']]);
However, when I try and redirect to the profile/{id} method using the following:
redirect()->route('profile', [$userId]);
I get the following error:
InvalidArgumentException in UrlGenerator.php line 278:
Route [profile] not defined.
What could be the issue?
The route method takes a route name as the first argument. All specific resource routes will get their own names, however there's none created with the name of the base resource (profile).
By running php artisan route:list you will see a list of all routes along with their names. For you it should look something like this:
+--------+----------+-----------------------------------------+-----------------+---------------------------------------------------+------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-----------------------------------------+-----------------+---------------------------------------------------+------------+
| | POST | profile | profile.store | App\Http\Controllers\ProfileController#store | |
| | GET|HEAD | profile | profile.index | App\Http\Controllers\ProfileController#index | |
| | GET|HEAD | profile/create | profile.create | App\Http\Controllers\ProfileController#create | |
| | PATCH | profile/{profile} | | App\Http\Controllers\ProfileController#update | |
| | PUT | profile/{profile} | profile.update | App\Http\Controllers\ProfileController#update | |
| | DELETE | profile/{profile} | profile.destroy | App\Http\Controllers\ProfileController#destroy | |
| | GET|HEAD | profile/{profile} | profile.show | App\Http\Controllers\ProfileController#show | |
| | GET|HEAD | profile/{profile}/edit | profile.edit | App\Http\Controllers\ProfileController#edit | |
+--------+----------+-----------------------------------------+-----------------+---------------------------------------------------+------------+
So since it seems you are intending to show a user profile, this should be what you are looking to do:
redirect()->route('profile.show', [$userId]);
Try redirect this way
return redirect('profile/2');
I'm grouping profile controller and I want to link to that. Then I define this route:
//Group to put all the routes that need login first
Route::group(array('prefix'=> 'admin', 'before' => 'csrf'), function(){
Route::resource('/profile' , 'ProfileController', array('as'=>'profile') );
});
and this is my menu link:
<li>profile Managment</li>
and this it my result of route in terminal:
+--------+----------------------------------+------------------------+---------------------------+----------------+---------------+
| Domain | URI | Name | Action | Before Filters | After Filters |
+--------+----------------------------------+------------------------+---------------------------+----------------+---------------+
| | GET / | index | Closure | | |
| | GET admin/index | dashboard | Closure | | |
| | GET logout | logout | Closure | | |
| | POST auth | auth | Closure | csrf | |
| | GET login | login | Closure | | |
| | GET admin/profile | admin..profile.index | ProfileController#index | csrf | |
| | GET admin/profile/create | admin..profile.create | ProfileController#create | csrf | |
| | POST admin/profile | admin..profile.store | ProfileController#store | csrf | |
| | GET admin/profile/{profile} | admin..profile.show | ProfileController#show | csrf | |
| | GET admin/profile/{profile}/edit | admin..profile.edit | ProfileController#edit | csrf | |
| | PUT admin/profile/{profile} | admin..profile.update | ProfileController#update | csrf | |
| | PATCH admin/profile/{profile} | | ProfileController#update | csrf | |
| | DELETE admin/profile/{profile} | admin..profile.destroy | ProfileController#destroy | csrf | |
+--------+----------------------------------+------------------------+---------------------------+----------------+---------------+
Now I get this error:
ErrorException
Route [admin.profile] not defined. (View: /var/www/alachiq/app/views/back_end/menu.blade.php) (View: /var/www/alachiq/app/views/back_end/menu.blade.php) (View: /var/www/alachiq/app/views/back_end/menu.blade.php)
Remove the / character from your Route::resource method. It is causing the double dots, which in turn are causing your error message.
Should be:
Route::resource('profile' , 'ProfileController', array('as'=>'profile') );
Either format (/profile or profile) would usually work, but when using the prefix option with Route::group you need to remove the / from resource URL.
EDIT: Also it seems to me that you should be pointing your link to route admin.profile.index, not admin.profile.
Why don't you just do URL::to('admin/profile');
Since what you're trying to achieve with URL::route('admin.profile'); is almost the same number of types away.
Now from what I understand, URL::route('profile'); will produce a full URL string to a a route with the same name you assigned to.
EDIT
echo URL::route('admin.profile.index');
Should work. Based from Docs, you should include .index under ROUTE NAME.
Solution For Laravel 5.6 and above
First step: do php artisan route:list in the terminal of your IDE.
Second step: find the admin/profile in the URI column.
Third step: in the Name column related to that uri you should find some thing like
profile.index
Last Step: You should use name provided in third step in your href.
Note: Contrary to laravel 5.3 in laravel 5.6 and above using admin.profile.index would not work