Reputation: 8770
The question title is the most explicit I could think of, but here's a use case/example for clarity's sake:
Say I define the following route to show an article:
Route::get('article/{slug}/{id}', 'ArticleController@show');
...
class ArticleController extends BaseController {
public function show($id)
{
return View::make('article')->with('article', Article::find($id));
}
}
This won't work, as show
will misake the $id
parameter with the $slug
parameter. Is there a way to pass only the $id
parameter to the show
method?
Upvotes: 4
Views: 4469
Reputation: 786
I dont know if you still look for solution or not, but as I had the same problem and I didn't like these solutions, I did this:
in the your ArticleController
you overload the callAction($method, $parameters)
method, this is a method in Laravel controller class, so it looks like this:
public function callAction($method, $parameters)
{
unset($parameters['id']);
unset($parameters['slug']);
return parent::callAction($method, $parameters);
}
after this you ca easily do this:
public function show($id)
{
return View::make('article')->with('article', Article::find($id));
}
Upvotes: 10
Reputation: 8770
It's possible to manually call controller functions:
Route::get('article/{slug}/{id}', function($slug, $id)
{
return App::make('ArticleController')->show($id);
});
Upvotes: 5
Reputation: 4117
You can certainly "ignore" parameters with Laravel -- i.e. make them optional -- by adding a question mark after their name:
Route::get('article/{slug?}/{id?}', 'ArticleController@show');
Note that you are limited by PHPs way of handling optional function arguments: the leftmost arguments cannot be optional if you have required ones to the right.
// Do
Route::get('article/{id}/{slug?}', 'ArticleController@show');
...
function show($id, $slug = null) {}
// Don't
Route::get('article/{slug?}/{id}', 'ArticleController@show');
...
function show($slug = null, $id) {}
I do agree with comments above saying it might not be entirely logical to do so. You will need either slug
or id
to lookup your article in the database, but at the same time you'd hope only of them would suffice to find the exact same article.
If you really want to have an optional slug in order to make your URLs more "crawlable", SEO-firendly, memorable or what have you, here's a suggestion, building from the example above:
Route::get('article/{id}/{slug?}', array(
'as' => 'article.show',
'uses' => 'ArticleController@show'
));
...
function show($id, $slug = null)
{
$article = Article::find($id);
if (!$slug) {
return Redirect::route('article.show', array($id, $article->slug));
}
...
}
I see no reason why anyone would try to access a slug-less URL, but that may be up to you and what you're trying to do with your app. This way at least you'd make the slug "optional", while making sure everyone ends up in the same spot with the full URL.
Upvotes: 3