Expansion of laravel Route::resource laravel 7 - php

For middleware reasons I decided to expand my current Route::resource routes on Laravel 7. However, I do want to make sure routes are expanded properly and identically so there are no issues in future. I came up with this list of routes :
Route::get('checklists', 'ChecklistController#index')->name('checklists.index');
Route::get('checklists/create', 'ChecklistController#create')->name('checklists.create');
Route::post('checklists', 'ChecklistController#store')->name('checklists.store');
Route::get('checklists/{checklist}', 'ChecklistController#show')->name('checklists.show');
Route::get('checklists/{checklist}/edit', 'ChecklistController#edit')->name('checklists.edit');
Route::match(['PUT', 'PATCH'], 'checklists/{checklist}', ['as' => 'checklists.update', 'uses' => 'ChecklistController#update']);
Route::delete('checklists/{checklist}', 'ChecklistController#destroy')->name('checklists.destroy');
instead of:
Route::resource('checklists', 'ChecklistController');
It may be a bit weird question, but could anyone confirm if this expanded version would generate an exact replacement for Route::resource? And if not, what else do I need to do to make sure it works exactly same? I could not find that information.

Maybe not an exact answer to your question, however I think your code would be a lot cleaner if you just used what is needed and appended the remainder
Route::resource('checklists', 'ChecklistController')->except('update');
Route::match(['PUT', 'PATCH'], 'checklists/{checklist}', ['as' => 'checklists.update', 'uses' => 'ChecklistController#update']);

Related

URL hit the wrong controller LARAVEL

In route.php I defined a route to a controller with 2 tokens on it.
Route::get('/{category}/{slug}', 'projectController#detail');
Everything is working fine till when there is a call to a URL that have the same structure but has nothing to do with the one that has to be caught by that route shown below.
So when I have for example "/admin/tags", the controller below is triggered because it has the same structure of "/{category}/{slug}" and of course it gives me an error, because it doesn't find a variable.
So now I fixed the problem moving that route on the bottom, but I believe I have to do something to prevent this behavior in advance, cause if I have multiple routes with different tokens everything would be triggered every time and there would be a mess.
So, what is it supposed to do in these cases?
P.S. I'm super beginner with Laravel
use some constraint to the route, reference parameters-regular-expression-constraints. For example:
Route::get('user/{name}', function ($name) {
//
})
->where('name', '[A-Za-z]+');
Or you can make the most specific before unspecific one. For example, in this sequence:
Route::get("/admin/tags", '......');
Route::get('/{category}/{slug}', 'projectController#detail');
if route need two token like that, i'm usually add prefix so my routes looks like this
Route::get('/categories/{category}/slug/{slug}', 'ProjectController#detail');
or
Route::get('/categories/{category}/{slug}', 'ProjectController#detail');
I was having the same issue.
I have constraints on every path parameter (as you always should) and unfortunately the conflict occurs between the following:
Route::get('{userId}/{path}', [
'as' => 'products',
'uses' => 'HomeController#click'
])->where(['id' => '[0-9]+', 'path' => '[0-9a-fA-F]+']);
Route::get('link/{link_path}', [
'as' => 'product-link',
'uses' => 'UserController#productLink'
])->where(['link_path' => '[0-9a-fA-F]+']);
Where even though the one path has the prepended 'link/' in the path it still tried to hit the other. By placing the route with the prepended 'link/' above the other route it took priority and works.
Personally I think if you have a condition that isn't met on the route where clause it should skip the route and move on to the next. It doesn't really make sense to me to put a conditional that doesn't actually get passed up if the conditions aren't met.
Hopefully this helps anyone else having this issue.

Laravel says "Route not defined"

In my routes.php I have:
Route::patch('/preferences/{id}', 'UserController#update');
And in the view file (account/preferences.blade.php) I have:
{!! Form::model(Auth::user(), ['method' => 'PATCH', 'route' => '/preferences/' . Auth::user()->id]) !!}
But I'm getting this error:
Route [/preferences/1] not defined
A similar error occurs when calling the route() helper directly:
route('/preferences/' . Auth::user()->id');
I think I'm misunderstanding the docs on this topic but I've defined a route for PATCH requests with a given parameter, and set this in the view correctly. What am I overlooking here?
The route() method, which is called when you do ['route' => 'someroute'] in a form opening, wants what's called a named route. You give a route a name like this:
Route::patch('/preferences/{id}',[
'as' => 'user.preferences.update',
'uses' => 'UserController#update'
]);
That is, you make the second argument of the route into an array, where you specify both the route name (the as), and also what to do when the route is hit (the uses).
Then, when you open the form, you call the route:
{!! Form::model(Auth::user(), [
'method' => 'PATCH',
'route' => ['user.preferences.update', Auth::user()->id]
]) !!}
Now, for a route without parameters, you could just do 'route' => 'routename', but since you have a parameter, you make an array instead and supply the parameters in order.
All that said, since you appear to be updating the current user's preferences, I would advise you to let the handling controller check the id of the currently logged-in user, and base the updating on that - there's no need to send in the id in the url and the route unless your users should need to update the preferences of other users as well. :)
This thread is old but was the first one to come up so I thought id share my solution too. Apart from having named routes in your routes.php file. This error can also occur when you have duplicate URLs in your routes file, but with different names, the error can be misleading in this scenario. Example:
Route::any('official/form/reject-form', 'FormStatus#rejectForm')
->name('reject-form');
Route::any('official/form/accept-form', 'FormStatus#acceptForm')
->name('accept-form');
Changing one of the names solves the problem. Copy, pasting, & fatigue can lead you to this problem :).
If route is not defined, then check web.php routing file.
Route::get('/map', 'NavigationController#map')->name('map'); // note the name() method.
Then you can use this method in the views:
<a class="nav-link" href="{{ route('map') }}">{{ __('Map') }}</a>
PS: the __('Map') is to translate "Map" to the current language.
And the list of names for routes you can see with artisan command:
php artisan route:list
I'm using Laravel 5.7 and tried all of the above answers but nothing seemed to be hitting the spot.
For me, it was a rather simple fix by removing the cache files created by Laravel.
It seemed that my changes were not being reflected, and therefore my application wasn't seeing the routes.
A bit overkill, but I decided to reset all my cache at the same time using the following commands:
php artisan route:clear
php artisan view:clear
php artisan cache:clear
The main one here is the first command which will delete the bootstrap/cache/routes.php file.
The second command will remove the cached files for the views that are stored in the storage/framework/cache folder.
Finally, the last command will clear the application cache.
when you execute the command
php artisan route:list
You will see all your registered routes in there in table format .
Well there you see many columns like Method , URI , Name , Action .. etc.
So basically if you are using route() method that means it will accept only name column values and if you want to use URI column values you should go with url() method of laravel.
One more cause for this:
If the routes are overridden with the same URI (Unknowingly), it causes this error:
Eg:
Route::get('dashboard', ['uses' => 'SomeController#index', 'as' => 'my.dashboard']);
Route::get('dashboard/', ['uses' => 'SomeController#dashboard', 'as' => 'my.home_dashboard']);
In this case route 'my.dashboard' is invalidate as the both routes has same URI ('dashboard', 'dashboard/')
Solution: You should change the URI for either one
Eg:
Route::get('dashboard', ['uses' => 'SomeController#index', 'as' => 'my.dashboard']);
Route::get('home-dashboard', ['uses' => 'SomeController#dashboard', 'as' => 'my.home_dashboard']);
// See the URI changed for this 'home-dashboard'
Hope it helps some once.
My case is a bit different, since it is not a form but to return a view. Add method ->name('route').
MyView.blade.php looks like this:
CATEGORIES
And web.php routes file is defined like this:
Route::view('admin', 'admin.index')->name('admin');
i had the same issue and find the solution lately.
you should check if your route is rather inside a route::group
like here:
Route::group(['prefix' => 'Auth', 'as' => 'Auth.', 'namespace' => 'Auth', 'middleware' => 'Auth']
if so you should use it in the view file. like here:
!! Form::model(Auth::user(), ['method' => 'PATCH', 'route' => 'Auth.preferences/' . Auth::user()->id]) !!}
In my case the solution was simple:
I have defined the route at the very start of the route.php file.
After moving the named route to the bottom, my app finally saw it.
It means that somehow the route was defined too early.
On a side note:
I had the similar issues where many times I get the error Action method not found, but clearly it is define in controller.
The issue is not in controller, but rather how routes.php file is setup
Lets say you have Controller class set as a resource in route.php file
Route::resource('example', 'ExampleController');
then '/example' will have all RESTful Resource listed here:
http://laravel.com/docs/5.0/controllers#restful-resource-controllers
but now you want to have some definition in form e.g: 'action'=>'ExampleController#postStore' then you have to change this route (in route.php file) to:
Route::controller('example', 'ExampleController');
Please note that the command
php artisan route:list
Or to get more filter down list
php artisan route:list | grep your_route|your_controller
the forth column tells you the names of routes that are registered (usually generated by Route::resource)
In my case, I was using a duplicate method. I was trying to update like this:
Route::get('/preferences/{id}', 'UserController#edit');
Route::get('/preferences/{id}', 'UserController#update');
When what I meant to do was something similar to this:
Route::get('/preferences/{id}', 'UserController#edit');
Route::post('/preferences/{id}', 'UserController#update');
Notice the get and post methods are different but the URLs are the same.

Possible to Or Laravel Routes?

I’m building a bilingual site in Laravel 4 and my URLs contain a locale identifier. Beyond that, it’s important to have nice looking slugs in the right language. So, let’s say I have a route at which you would find mugs. The equivalent in French would be tasses.
Currently what I'm doing is
Route::get('{locale}/mugs', ['uses' => 'MugsController#index']);
Route::get('{locale}/mugs/{id}', ['uses' => 'MugsController#show']);
Route::get('{locale}/tasses', ['uses' => 'MugsController#index']);
Route::get('{locale}/tasses/{id}', ['uses' => 'MugsController#show']);
And a short URL/locale check and redirect in the controller methods that makes sure that the slug is in the right language, so you don't end up with /fr/mugs, for example.
This works ok but may get unwieldy since I will have two of each if I make any more routes. For example, I'd have to have both {locale}/mugs/ceramic/{id} and {locale}/tasses/ceramique/{id}, etc.
Is there a way to do something like {locale}/mugs|tasses/{id} in Laravel? Or even check with RegEx?
I know you can check the route parameters with RegEx, but can you check the actual path components?
You can create regex patterns, and do things like:
Route::pattern('mugs', 'mugs|tasses');
Route::get('{locale}/{mugs}', ['uses' => 'MugsController#index']);
Route::get('{locale}/{mugs}/{id}', ['uses' => 'MugsController#show']);
You can do it this way:
Route::get('{locale}/{special}', ['uses' => 'MugsController#show'])->where('special','^(mugs|tasses)$');
special in this case must be either mugs or tasses

Laravel Route::resource naming

I have the following in my routes.php
Route::resource('g', 'GameController');
I link to these generated routes via HTML::linkRoute('g.index', 'Title', $slug) which produces a link to http://domain/g/demo-slug
What I am looking to do is verify if it is possible to have the prefix be declared in one place so I'm not hunting for links if a URL structure were to change.
For example, I would want to change http://domain/g/demo-slug to http://domain/video-games/demo-slug
I was hoping to use the similar functionality with the standard routes, but that does not seem to be available to resource routes.
Route::get('/', array('as' => 'home', 'uses' => 'HomeController#getUpdated'));
Route::group() takes a 'prefix'. If you put the Route::resource() inside, that should work.
Tangent, I find this reads better:
Route::get('/', array('uses' => 'HomeController#getUpdated', 'as' => 'home'));
As far as I know it's true you can't have named routes for a resource controllers (sitation needed) but you can contain them in a common space using Route::group() with a prefix. You can even supply a namespace, meaning you can swap out an entire api with another quickly.
Route::group(array(
'prefix' => 'video-games',
'before' => 'auth|otherFilters',
'namespace' => '' // Namespace of all classes used in closure
), function() {
Route::resource('g', 'GameController');
});
Update
It looks like resource controllers are given names internally, which would make sense as they are referred to internally by names not urls. (php artisan routes and you'll see the names given to resource routes).
This would explain why you can't name or as it turns out is actually the case, rename resource routes.
I guess you're probably not looking for this but Route:group is your best bet to keep collections of resources together with a common shared prefix, however your urls will need to remain hard coded.
You can give custom names to resource routes using the following syntax
Resource::route('g', 'GameController', ['names' => [
'index' => 'games.index',
'create' => 'games.create',
...
]])
This means you can use {!! route('games.index') !!} in your views even if you decided to change the URL pattern to something else.
Documented here under Named resource routes

Laravel 4 - Hide variables from URL.

I have the following Route:
Route::resource('projects.deliveries.tasks', 'TaskController');
And of course if I want to create a task, my URL looks like this:
http:://test.dev/projects/1/deliveries/3/tasks/create
For Project Number 1 and delivery number 3.
http://i.imgur.com/RlHHY31.jpg
But I don't want the number to show up in the URL, because tasks should be creatable, without authentication or login.
Is there a way to hide these numbers, so that I get a clean URL like this:
http:://test.dev/projects/delivereis/tasks/create
And Laravel understands from my logic, that it is Project 1 and devivery 3 for which a task is to be created?
If you want to do this, you should probably specify your routes manually. Using Route::resource() is great if you're absolutely going to use the resource as intended (with verbose routes) but it doesn't provide you with much flexibility. In fact for most projects it's actually recommended that you do define all your routes manually to give you the most control (and it's also great self-documentation in your routes.php file).
Route::get('projects/deliveries/tasks/create', ['as' => 'projects.deliveries.tasks.create', 'uses' => 'TasksController#create']);
Route::post('projects/deliveries/tasks', ['as' => 'projects.deliveries.tasks.store', 'uses' => 'TasksController#store']);

Categories