Reputation: 22630
I'm writing routing for an app that will have a lot of similar routes, and I want to keep things DRY, so I want to choose the controller based on a segment of the URL, but there doesn't seem to be a way to do this with Laravel.
This doesn't work, because the $report_slug
is not available.
Route::get('/ad-reports/{report_slug}', array('uses' => Str::title($report_slug).'Controller@showHome'));
If I use a closure I have access to $report_slug
, but I can't find any documentation for what to replace return
with, so this returns the text of the controller and action, but obviously I want to use that action.
Route::get('/ad-reports/{report_slug}', function($report_slug) {
return (Str::title($report_slug).'Controller@showHome');
});
How can I specify the controller based on the report_slug
?
Upvotes: 0
Views: 1103
Reputation: 198
You can call App::make in route like below. It'll work as you want
Route::get('/ad-reports/{report_slug}', function($report_slug) {
return App::make($report_slug.'Controller')->showHome();
});
Upvotes: 4
Reputation: 87769
To use it dinamically you can do:
Route::get('ad-reports/{report_slug}', Str::title(Request::segment(2)).'Controller@run');
Worked for me, this is the controller I used to test this route:
class FooController extends Controller {
public function run()
{
return "this is a dynamic controller call";
}
}
You can create a proxy controller to find your controllers based on your route parameters:
class ProxyController extends Controller {
public function __call($name, $arguments)
{
$class = Str::title($arguments[0]).'ReportController';
array_shift($arguments);
$controller = new $class;
return call_user_func_array(array($controller, $name), $arguments);
}
}
This is the route:
Route::any('ad-reports/{report_slug}', 'ProxyController@bar');
This is a controller example:
class FooReportController extends Controller {
public function bar()
{
return 'generated by foo report!';
}
}
And you just have to hit
http://yourdomain.com/ad-reports/foo
To see:
generated by foo report!
Upvotes: 6