iconoclast
iconoclast

Reputation: 22630

Dynamically choose controller

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

Answers (2)

Muharrem Tigdemir
Muharrem Tigdemir

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

Antonio Carlos Ribeiro
Antonio Carlos Ribeiro

Reputation: 87769

Option 1

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";
    }

}

Option 2

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

Related Questions