0

I am using Laravel. I would like users to be able to perform a search on my website using up to 3 criteria. These criteria are: Class, Brand and Model.

They should be free to use any or all of them when searching. As the relationship between these isn't as simple as Many->1, Many->1, Many->1, and also given the criteria will be numbered if blank, I dont want to use pretty urls to post the search criteria as they would look like this:

/SearchResults/0/BMW/0

which is meaningless to users and search engines. I therefore want to use normal dynamic addresses for this route as follows:

/SearchResults/?Class=0&Brand="BMW"&Model=0

How do I define a route that allows me to extract these three criteria and pass it to a custom method in my resource controller?

I have tried this but it isnt working:

Route::get('/SearchResults/?Class={$class}&Brand={$brand}&Model={$type}', 'AdvertController@searchResults');

Many thanks

Ben Thompson
  • 4,743
  • 7
  • 35
  • 52

2 Answers2

0

The Symfony Routing components fetch the REQUEST_URI server variable for matching routes, and thus Laravel's Route Facade would not pick up URL parameters.

Instead, make use of Input::get() to fetch them.

For example, you would start by checking if the class param exists by using Input::has('class'), and then fetching it with Input::get('class'). Once you have all three, or just some of them, you'd start your model/SQL query so that you may return your results to the user.

Mike Rockétt
  • 8,947
  • 4
  • 45
  • 81
  • That makes sense - Im happy to retrieve the params this way, but I still need to route to the correct class method - how would I do this while ignoring the params? – Ben Thompson Jul 23 '13 at 06:45
  • If I'm understanding you correctly, you would only need to map the `SearchResults` route to your `AdvertController@SearchResults` method. The parameters will be available there anyway... – Mike Rockétt Jul 23 '13 at 13:14
0

You will need to route all to the same method and then, within the controller, reroute that given action to the correct method within the controller.

For that, I recommend using the strategy pattern (read more here).

I would do something like this:

route.php

Route::get('/SearchResults', 'AdvertController@searchResults');

AdvertController.php

use Input;
...
private $strategy = [];
public function __construct(){
    $strategy = [
        /*class => handler*/
        '0'=> $this->class0Handler,
        '1'=>$this->class1Handler,
        ...];
}
private function class0Handler(){
    //your handler method
}
public function searchResults(){
    if( !array_key_exists(Input::get('class'),$this->strategy))
        abort(404);
    return $this->strategy[Input::get('class')]();
}

In case you are breaking down search by other types, you define the handler in the $strategy variable.

Strategy pattern has a lot of benefits. I would strongly recommend it.