Last active
May 19, 2020 10:22
-
-
Save oliviagardiner/e4d3035130614556a824ee9ffa397ec0 to your computer and use it in GitHub Desktop.
How to sort & filter a Yii2 active query generated with findBySql()
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* If you try to pass a query generated with findBySql() to an ActiveDataProvider, | |
* you will find that the convenient filtering and sorting methods won't work on your query, | |
* because the SQL statement is already specified. | |
* | |
* See: https://www.yiiframework.com/doc/api/2.0/yii-db-activerecord#findBySql()-detail | |
* | |
* However, if you use an ArrayDataProvider instead of an ActiveDataProvider, | |
* not only will your query be sortable, but pagination will work too. | |
* | |
* This is what I'm going to demonstrate here, with a workaround for filtering. | |
* | |
* Please note that generally, you are better off using ActiveDataProvider, but sometimes | |
* findBySql() might be needed for very complex queries. | |
*/ | |
namespace app\modules\example\models; | |
use Yii; | |
use yii\data\ArrayDataProvider; | |
use app\modules\example\models\MyModel; | |
class MyModelSearch extends MyModel | |
{ | |
public function rules() | |
{ | |
return [ | |
[['model_id'], 'integer'] | |
[['model_name'], 'string'] | |
]; // define your rules here like you always do | |
} | |
public function search($params) | |
{ | |
$this->load($params); | |
$filters = []; | |
if ($this->model_id) $filters[] = ' "table_name"."model_id" = '.$this->model_id.' '; | |
if ($this->model_name) $filters[] = ' "table_name"."model_name" ILIKE \'%'.$this->model_name.'%\' '; | |
// ugly ifs can be put into a foreach if you don't need to customize each condition too much | |
$filterCondition = count($filters) > 0 ? ' AND '. implode(' AND ', $filters) : ' '; | |
$query = MyModel::findBySql( | |
// your query here | |
.$filterCondition. | |
// group by, order by etc. | |
); | |
$sort = [ | |
'attributes' => [ | |
'model_id', | |
'model_name' | |
], | |
'defaultOrder' => [ | |
'model_name' => SORT_ASC | |
] | |
]; | |
$dataProvider = new ArrayDataProvider([ | |
'allModels' => $query->all(), | |
'sort' => $sort, | |
'pagination' => [ | |
'pageSize' => 30, | |
] | |
]); | |
return $dataProvider; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Switch condition for grouping filters: