Building a search GET request with scenarios ; calling a SearchModel from URLs...

Search Models are a very elegant and powerful way to build an Active Data Provider. If you use them a lot, you'll quickly need to use scenarios, which will lead you to a very DRY Controller code.

Doing so, you'll maybe want to call one of your scenarios from URL, and to parse to it some variables from URL, like :

index.php?r=mycont/myaction&scenario=MY_SCENARIO&variable=my_value...

The scenario could be also defined inside the controller rather than in URL.

But the important part here, is that a variable you want to use inside a specific scenario is defined in the URL.

If you do it in the usual way in the controller, parsing the request directly to the search model, and using the ModelSearch generated by Gii, you'll have an error, like an SQL error, saying that variable is not defined.

This come from the /app/model/ModelSearch::search() methods generated by Gii. It waits for a post request coming from a Form, rather than a GET request coming from an URL. It parse a single paramater to /yii/base/Model::load($params, $formName). This Yii methode can also deal with a GET request if you give it a second empty parameter (load($parmater, '')). But the /app/models/ModelSearch::search() method generated by Gii doesn't provide this case.

To handle that, just change the search function generated by Gii :

/app/model/ModelSearch::search()

class PostSearch extends Post
{

    public $param;
    public function rules()
    {
        ...
        [['param'], 'string', 'on' => 'MY_SCENARIO'],
        ...
    }

    ...
    
    public function search($params)
    {
        ...
        // Replace : $this->load($params) by :
        (isset$params['ModelSearch'])?$this->load($params):$this->load($params, '');
        ....
    }

Now, inside the controller, you can parse the GET request to the the search method in the usual simple way :

/app/controllers/MyCont::actionMyaction()

public function actionMyaction($params)
{
    ...
    // We get the params from GET request
    $params = Yii::$app->request->queryParams;
    // we parse them to /app/model/ModelSearch::search() 
    $dataProvider = $searchModel->search($params);
    ....
}

And that's all. Now, inside the /app/model/ModelSearch::search() method, you will have access to my_value inside $this->param to do what you want.

Also, be careful, you must NOT use quotes inside the url to define scenario. Eg :

(WRONG :) index.php?r=mycont/myaction&scenario="MY_SCENARIO"&param=my_parameter

(RIGHT :) index.php?r=mycont/myaction&scenario=MY_SCENARIO&param=my_parameter

0 0
2 followers
Viewed: 16 767 times
Version: 2.0
Category: Tips
Written by: Louis Gac
Last updated by: Louis Gac
Created on: Apr 28, 2015
Last updated: 5 years ago
Update Article

Revisions

View all history

Related Articles