Laravel named routes parameter not working correctly - php

I'm currently using Laravel 5.3 and i have a number of routes similar to.
Route::get('/news/create/{product}', 'NewsController#create')->name('news::create');
So in my blade template im using the route() function like so:
{{route('news::create','car')}}
But the url generated is
/news/create?car
not the required
/news/create/car
The same thing happens if i put it in an array:
{{route('news::create',['car'])}}
And if i give it a key like so:
{{route('news::create',['product'=>'car'])}}
I get:
/news/create?product=car
How do I get the correct url so it is passed to the 'create' function as a parameter?

Firstly, take a look at your route naming. I don't think there's anything specifically wrong with naming a route like 'news::create' apart from it being ugly and quite probably considered bad practice. I like to go with camel casing, which means I'd use a name like createNews. It's much easier when going back to work on old sections of code and will stop other programmers from stabbing you if/when they work on a project with you.
The reason we can name routes is so that the name stays static even if we change the route URI or controller endpoint. We can pass variables to it using route parameters.
Route::get('/news/create/{product}', array('as' => 'createNews', 'uses' => 'NewsController#create'));
route('createNews', ['product' => 'car']);

{{route('news::create',['product => 'car'])}}
Should fix your problem. Laravel uses named routes and expects an array with the keys as names with values.
Read all about it here: https://laravel.com/docs/5.3/redirects#redirecting-named-routes

Related

Escape forward slash in laravel

I have dozens of routes like the following list
Route::group([
'where' => ['aNumber' => '.*'],
], function () {
Route::get('air/{aNumber}/tools', 'AirController#tools');
Route::post('air/{aNumber}/handled', 'AirController#handled');
Route::post('air/{aNumber}/notHandled', 'AirController#notHandled');
Route::get('air/{aNumber}/act', 'AirController#act');
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
Route::get('air/{aNumber}', 'AirController#show');
});
the {anumber} parameter could be like these 23-349493/4 While this kind of parameter will produce some conflicts with other routes, So for example if we are going to call air/28-23422/sendAct then instead of calling #sendAct route, it'll call #show.
because laravel thinks that /sendAct is part of the parameter. Well, I can fix this problem by adding more where not(Regex) on each of the routes and define the logic that every route should follow, But do you have a better solution for this problem?
No, you are wrong, Laravel will choose show since air/28-23422/sendAct won't hit sendAct because sendAct has as supposed method POST, and not GET.
Instead of:
Route::post('air/{aNumber}/sendAct', 'AirController#sendAct');
try writing
Route::get('air/{aNumber}/sendAct', 'AirController#sendAct');
// ^^^
Or use ^[^\/]* as where clause of the group for aNumber

Laravel how to generate urls using GET route names?

I got this 2 routes in my routes file (web)
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
Route::post('management/special-fees/add', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
They both share the same name but one is GET and the other is POST, so far so good. But now I want to make an url in my view to open the form, for that I use the method route() like this
route('management/special-fees/add',$user->id )
but when trying to go to the url I get this route
.../management/special-fees/add?5
there is a question mark instead of a "/" so the route is invalid.
I made some tests and I figured out that happens because is trying to go to the POST route instead of the GET one if I change the POST route's url in the web file like this
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
Route::post('management/special-fees/addSSSS', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
I will in fact get this url
.../management/special-fees/addSSSS?5
So why is the route() method generating a url for the POST route over the GET one? how do I make it to choose the GET route first?
In laravel the routing is prioritized by in the order it is written in your route.php file.
In this case you're writing the Route::post last, which in turn tells Laravel that that one should have the highest priority. Try switching them and the Route::get will have the higher priority.
Like so:
Route::post('management/special-fees/addSSSS', 'Management\SpecialFeeController#store')->name('management/special-fees/add');
Route::get('management/special-fees/add/{userId}', 'Management\SpecialFeeController#create')->name('management/special-fees/add');
I may be wrong, but I think you'll have to re-think route naming. One of the problems route naming helps eliminate is redundant and complex names. For example, if you looked at route:list for Route::resource('something', 'SomethingController') it will have something.index, something.store as route names for Route::get('something') and Route::post('something').
If it's the same name, it will always resolve to the first one and will probably never hit the second route; in your case will hit the POST route and never the GET route.
?5 means 5 is an argument for your get route.
try this
url('management/special-fees/add/'.$user->id)
for get route insted of
route('management/special-fees/add',$user->id )

Laravel named routing | Auto generating urls to best possible match

I am trying to name my routes so I can easily generate urls instead of using the url helper function in which I have to type myself.
I am doing this:
Route::get('logout', 'PageController#logout')->name('pc');
When I do php artisan route:list I don't get this named route, instead name column is empty.
What I want is that, whatever views I target through this controller. I want to generate their urls like this.
route('pc.logout') OR route('pc.some_other_action')
So even if I change the verb to access this controller from the URL address, I don't have to change my url generator. Is this even possible in Laravel? Please also tell how to do this for resource routes.
I am using Laravel 5.3.
Thanks.
EDIT: Next day 1/11/2017
What I am expecting is that like ASP.NET MVC routing, if I tell it to generate a url with given controller and actions, it will generate the possible route to it regardless of the verb or string used to name the route.
For example
If I make a url like this
route('users.index')
Outputs /users
but if I change the string name users to u, instead of giving me error that name 'users' doesn't exist it should auto generate a url output like this:
Output: /u
This is a part of ASP.NET MVC routing system, I am expecting to see this here as well.
You should write this This will solve your problem
Route::get('logout', array('as' =>'pc.logout' ,'uses' => 'PageController#logout'));
This might solve your problem
you can define the named route as this
Route::get('/logout',[
'uses'=>'web\PageController#logout',
'as'=>'pc'
]);
Try this:
<?php
Route::get('logout',[
'uses'=>'PageController#logout',
'as'=>'pc.logout'
]);
name('pc.logout') OR name('pc.some_other_action')
You can try this one.
It is much simpler way to use:
Route::get('logout', 'PageController#logout')->name('pc.logout');
Or like this:
Route::get('logout', 'PageController#logout')->name('pc.some_other_action');
can you explain further if this is wrong.

Laravel 5 redirect to path with parameters (not route name)

I've been reading everywhere but couldn't find a way to redirect and include parameters in the redirection.
This method is for flash messages only so I can't use this.
return redirect('user/login')->with('message', 'Login Failed');
This method is only for routes with aliases my routes.php doesn't currently use an alias.
return redirect()->route('profile', [1]);
Question 1
Is there a way to use the path without defining the route aliases?
return redirect('schools/edit', compact($id));
When I use this approach I get this error
InvalidArgumentException with message 'The HTTP status code "0" is not valid.'
I have this under my routes:
Route::get('schools/edit/{id}', 'SchoolController#edit');
Edit
Based on the documentation the 2nd parameter is used for http status code which is why I'm getting the error above. I thought it worked like the URL facade wherein URL::to('schools/edit', [$school->id]) works fine.
Question 2
What is the best way to approach this (without using route aliases)? Should I redirect to Controller action instead? Personally I don't like this approach seems too long for me.
I also don't like using aliases because I've already used paths in my entire application and I'm concerned it might affect the existing paths if I add an alias? No?
redirect("schools/edit/$id");
or (if you prefer)
redirect("schools/edit/{$id}");
Just build the path needed.
'Naming' routes isn't going to change any URI's. It will allow you to internally reference a route via its name as opposed to having to use paths everywhere.
Did you watch the class Illuminate\Routing\Redirector?
You can use:
public function route($route, $parameters = [], $status = 302, $headers = [])
It depends on the route you created. If you create in your app\Http\Routes.php like this:
get('schools/edit/{id}', 'SchoolController#edit');
then you can create the route by:
redirect()->action('SchoolController#edit', compact('id'));
If you want to use the route() method you need to name your route:
get('schools/edit/{id}', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
// based on CRUD it would be:
get('schools/{id}/edit', ['as' => 'schools.edit', 'uses' => 'SchoolController#edit']);
This is pretty basic.
PS. If your schools controller is a resource (CRUD) based you can create a resource() and it will create the basic routes:
Route::resource('schools', 'SchoolController');
// or
$router->resource('schools', 'SchoolController');
PS. Don't forget to watch in artisan the routes you created

Laravel Routes: Use ::controllers and ::post

Within Laravel, I currently have:
Route::controllers([
'bla' => 'BlaController',
]);
But for a few specific methods within BlaController, I would like to pass parameters via the route (eg: /bla/parameter) and then be able to access that parameter within the controller.
However, declaring:
Route::get('bla/{parameter}', 'BlaController#exampleMethod');
keeps giving me a 404 not found when visiting it.
Is there some kind of conflict between using both declarations within routes.php and if so, is there a way to pass parameters to the controller for specific methods?
Edit: This is Laravel 5.1, if that makes any difference!
Can u try this ?
Route::get('/bla/{parameter}' ['uses'=>'BlaController#exampleMethod']);
http://laravel.io/forum/07-26-2014-routing-passing-parameters-to-controller

Categories