mwallisch
mwallisch

Reputation: 1810

Laravel: is it possible to set a controller dynamically for a route?

So, lets say I do have a simple Controller that handles Books.

App\Http\Controllers\SimpleBooksController

Inside routes.php I register a route for it:

Route::get('books/{id}','SimpleBooksController@doSimpleStuff');

But the world of books is not so simple. So I would like to have another Controller that handles the really complex book stuff.

In my head I imagine that something like this would be really useful:

class ComplexBooksController extends SimpleBooksController

So that routes that are not explicitly handled by the child class fall back to the parent class.

Now let's say each book knows if it is complex or not: $book->isComplex

And what I would like to do would be something like this

if (!$book->isComplex) {
    // route 'books/{id}' to SimpleBooksController@doSimpleStuff
} else {
    // route 'books/{id}' to ComplexBooksController@doComplexStuff
}

So, how could one accomplish this?

* edit *

The way I am currently handling this, is by setting the Controllers in routes.php statically, but let them listen to parameterized routes:

Route::get('books/simple/{id}', 'SimpleBooksController@doSimpleStuff');
Route::get('books/complex/{id}', 'ComplexBooksController@doComplexStuff');

Upvotes: 4

Views: 2719

Answers (2)

Laurence
Laurence

Reputation: 60058

Your approaching this in the wrong way. You should not be trying to handle it with different controllers and routes.

A route for books should be the same - regardless of the book.

Your controller then makes a determination if the book is simple or complex - and calls the appropriate Command to handle this.

Route:

Route::get('books/{id}','BooksController@doSimpleStuff');

Controller:

class BooksController extends Controller
{
      public function showBook($book)
      {
           if ($book->isComplex()) {
                $this->dispatch(new HandleComplexBook($book));
           } else {
                $this->dispatch(new HandleSimpleBook($book));
           }
      }

}

Then you just have two commands - one for simple books, and one for complex books

class HandleComplexBook extends Command implements SelfHandling {

    protected $book;

    public function __construct(Book $book)
    {
        $this->book = $book;
    }

    public function handle()
    {
        // Handle the logic for a complex book here
    }

}

class HandleSimpleBook extends Command implements SelfHandling {

    protected $book;

    public function __construct(Book $book)
    {
        $this->book = $book;
    }

    public function handle()
    {
        // Handle the logic for a simple book here
    }

}

Upvotes: 2

wavemode
wavemode

Reputation: 2116

According to the responses documentation, you should be able to use an anonymous function and return a redirect to the correct controller.

This assumes you have the data in a books table with isComplex:

Route::get('books/{id}', function($id) {

    $result = DB::select('SELECT is_complex FROM books WHERE id = ?', [$id]);

    if (empty($result)) abort(404);

    $book = $result[0];

    if ($book->is_complex)
        return redirect()->action('SimpleBooksController@doSimpleStuff');
    else
        return redirect()->action('ComplexBooksController@doComplexStuff');

});

Upvotes: 2

Related Questions