I have a homegrown, Laravel 5.1 base application on top of which I build specific applications. The base application uses a named route for login, naturally called "login", which listens for GET /login.
In one of my specific applications, I attempted to overload that route to send the requests to a different controller. It seemed to work for a while, but then it started going to the base application's controller again. I'm sure I changed something to break it, but the problem is that I can't figure out how to fix it again.
My base application routes are all defined in app/Http/Routes/core.php. The relevant route:
Route::get('login', [
'as' => 'login',
'uses' => '\MyVendor\Core\Http\Controllers\AuthController#getLogin'
]);
My specific application routes are defined in app/Http/Routes/app1.php. The relevant route:
Route::get('login', [
'as' => 'login',
'uses' => 'App1\AuthController#getLogin'
]);
App2 and App3 are defined similarly. My app/Http/routes.php adds these routes like this:
require 'Routes/core.php';
Route::group(['domain' => 'app1.com'], function() {
require 'Routes/app1.php';
});
Route::group(['domain' => 'app2.com', function() {
require 'Routes/app2.php';
});
Route::group(['domain' => 'app3.com', function() {
require 'Routes/app3.php';
});
The problem I am seeing is that visiting app1.com/login, app2.com/login, and app3.com/login all result in the execution of \MyVendor\Core\Http\Controllers\AuthController#getLogin rather than App1\AuthController#getLogin.
EDIT: I have changed the problem description since I was describing it incorrectly as a problem with calls to route('login').
The index of the routes in Laravel follows a "$domain$uri" format, therefore routes with a domain won't overwrite those without. A fallback route without a domain should be declared after the domain group, so it is later in the route collection and won't match before a route with a matching domain.
"the most recent definition for a route is the effective route"
This is not a bug, this is the expected behaviour, a simple example would be setting a variable to value 1 then setting it to value 2, of course the (most) recent value takes place.
what I'm trying to do is set it up so that the user can go to "/project/index" ("/" being the route ofc) but I'm not quite sure how to do it in laravel?
What I currently have:
Routing:
Route::get('project.index', array('as' => 'project/index', 'uses' => 'ProjectController#indexPage'));
Also in routing:
View::addLocation('project'); //Project View
View::addNamespace('project', 'project');
In my Project Controller:
public function indexPage()
{
return View::make('index', array('pageTitle' => 'Project Index'));
}
Any ideas? Thanks in advance.
PS: It's Laravel 4
You have your routing a little wrong. Try out the following
Route::get('project/index', ['as' => 'project.index', 'uses' => 'ProjectController#index']);
So the first parameter into the Route::get() function should be the URL the user is visiting for example http://example.com/project/index. The as key in the array provided is the name you're giving to the route.
By giving the route a name you can use this throughout your application, rather than using the url the user is visiting. For example you might want to generate a link to your route
Link
This will generate a link to http://example.com/project/index. This makes it convenient in the future should you wish to change your URLs without changing lots of links throughout your view files.
Route::get('foobar/index', ['as' => 'project.index', 'uses' => 'ProjectController#index']);
The URL generated through route('project/index') would now be http://example.com/foobar/index
Checkout the routing documentation for further information http://laravel.com/docs/4.2/routing
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.
I'm trying to understand routing in Laravel 4. I read a good post here on StackOverflow and a link to beware the route to evil, a post about manually specifying routes. I like the idea of specifying my routes manually and having the routes.php act as documentation. But it seems like I need to be cautious about the order of my Routes if I'm going to specify my own instead of using Route::resource() If I have the new or create route before the show then I won't be routed to the show because of the variable in URI? The order in which the routes are defined is important right?
// This will not work if I try and browse to dogs/new
Route::get('dogs', array('as' => 'dogs', 'uses' => 'DogsController#index'));
Route::get('dogs/{dogs}', array('as' => 'dog', 'uses' => 'DogsController#show'));
Route::get('dogs/new', array('as' => 'new_dog', 'uses' => 'DogsController#create'));
It seems I need to make sure that the dogs/new comes before the dogs/{dogs} for new to return correctly. I'm not clear on what {dogs} does or that's different from (:any) or {any} I've seen a few different uses in examples and pseudo code. I see that /new is the same as {...} when the route is before the more specific is the {} like a wildcard in Laravel 4? Is the (:...) the old way?
As an aside I've noticed a different naming convention from some of the examples I've seen when I run php artisan routes with a resource route like Route::resource('photos', 'PhotosController'); The method and named route for post to index to a create a new resource is named photos.store and #store. The method and named route for a link to a form to create a new resource is photos.create and #create. Is that Laravel 4 thing or conventions in other frameworks?
Route::get('dogs/{dogs}', array('as' => 'dog', 'uses' => 'DogsController#show'));
The above url expecting a parameter after dogs segment.
for example: http://laravel.com/dogs/xyz, http://laravel.com/dogs/new
after dogs url segment, Laravel will accept anything. So, your another routing will never executed for the route parameter.
Route::get('dogs/new', array('as' => 'new_dog', 'uses' => 'DogsController#create'));
More about route parameters:
http://laravel.com/docs/routing#route-parameters
Resource Controllers
Laravel and Ruby on rails support resource full routing. I think, Tailor borrow the resource full routing idea from Ruby on rails.
The following routes will generate if you use resource controller:
index
create
store
update
show
edit
destroy
http://guides.rubyonrails.org/routing.html
http://laravel.com/docs/controllers#resource-controllers
I got an annoying problem with a route, for a section of a CMS that I'm developing.
I got routes for all the sections, "products", for example:
Route::get('admin/products', array('as' => 'admin/products', 'uses'=> 'admin.products#index'));
Route::get('admin/products/create', array('as' => 'admin/products/create', 'uses'=> 'admin.products#create'));
Route::get('admin/products/edit/(:num)', array('as' => 'admin/products/edit', 'uses'=> 'admin.products#edit'));
Route::get('admin/products/delete/(:num)', array('as' => 'admin/products/delete', 'uses'=> 'admin.products#delete'));
.. and the related files, like the products controller, the product model and the views.
Everything was doing well until I decided to create a new section, "users". I used the same approach as "products", creating the routes and the other files. In fact I just copied and paste the files, making the changes when needed -- pretty straightforward. By accessing "admin/users" and "admin/users/create", it works as expected. But I can't access "/users/edit/1" and "/users/delete/1". I thought it would be a route problem, but when I tested the route file, I got a 404 even before reaching the route. Here's an example:
Route::get('admin/users/edit/(:num)', function()
{
return "Holy Hell.";
});
"Holy Hell" is never printed into the screen.
Here's the config for "users":
Route::get('admin/users', array('as' => 'admin/users', 'uses'=> 'admin.users#index'));
Route::get('admin/users/edit/(:num)', array('as' => 'admin/users/edit/', 'uses'=> 'admin.users#edit'));
Route::get('admin/users/create', array('as' => 'admin/users/create', 'uses'=> 'admin.users#create'));
Route::get('admin/users/delete/(:num)', array('as' => 'admin/users/delete', 'uses'=> 'admin.users#delete'));
Things that I noticed / Checked:
The index view, where is the users list, got a "URL::to_route('admin/users/edit')" function. I have no errors on the screen, so Laravel understands that the route 'admin/users/edit' is set correctly.
I know that this is not a general problem, because the "edit" and "delete" methods for the other CMS sections have no issues.
The views for these methods are there. So this is not a "file not found" issue.
I wonder if I'm missing something really obvious here. Any ideas? If not, would anyone please tell me how to debug this?
Thank you very much.
EDIT: Heads up
Your routes are in a bad order. Reverse them. Routes are evaluated top down, so anything with admin/products in the route will route to admin.products#index and nothing else.
In your edit method, you need to have the id parameter defined.
Since you didn't post your controller, I'm assuming this is why, since the closure does not have the $id passed to it. Example:
// Required user id:
Route::get('admin/users/edit/(:num)', function($id)
{
return "Holy Hell.";
});
// Optional user id:
Route::get('admin/users/edit/(:num?)', function($id = null)
{
return "Holy Hell.";
});
In your case, you probably don't want the optional part unless you plan on spewing out an error (or redirecting on error).