Aug 13 2013
Yii: фильтрация в связанных таблицах
При разработке CRUD приложения на yii может возникнуть необходимость фильтрации данных в связанных (объединённых) таблицах. Для формирования табличного представления используется виджет GridView. Столбцы задаются в элементе массива “columns”. Если имя столбика задано с использованием точки (например clientCourse.course_id) фильтрация и сортировка у столбца исчезает. Как её вернуть мы ниже и рассмотрим.
Имеем следующее:
Модели “Client”, “ClientCourse” и “CatalogCourse”.
Файл представления client/index.php, содержащий виджет “TbGridView”.
В файле модели “Client” задаём свойство
public $columnCourse;
В метод rules() вносим изменения в правило валидации, добавляем поле columnCourse:
public function rules()
{
return array(
//...
// The following rule is used by search().
// Please remove those attributes that should not be searched.
array('columnCourse, family, name, patronimic, forwho', 'safe', 'on'=>'search'),
);
}
Таблицы объединены следующим образом:
public function relations()
{
// NOTE: you may need to adjust the relation name and the related
// class name for the relations automatically generated below.
return array(
'clientCourse'=>array(self::HAS_MANY, 'ClientCourse', 'client_id'),
'catalogCourses'=>array(self::HAS_MANY, 'CatalogCourse', 'course_id', 'through'=>'clientCourse'),
);
}
Вносим изменения в метод search возращающий data provider необходимый для фильтрации в виджете:
public function search()
{
$criteria=new CDbCriteria;
$criteria->with = array('clientCourse');
// ...
$criteria->together = true;
$criteria->compare('clientCourse.course_id', $this->columnCourse);
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
'pagination'=>array(
'pageSize'=>20,
),
));
}
В фрагменте clientCourse – название связи (relations), columnCourse – созданное нами свойство в моделе Client.
Код файла представления приобретает следующий вид:
$this->widget('bootstrap.widgets.TbGridView', array(
'id'=>'client-grid',
'type'=>'striped bordered condensed',
'enableHistory'=>true,
'template'=>"{items}\n{pager}",
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'family',
'name',
'patronimic',
array(
'type'=>'raw',
'name'=>'columnCourse',
'filter'=>CatalogCourse::getAll(),
'value'=>'CatalogCourse::coursesToStr($data->catalogCourses,$data->clientCourse)',
),
array(
'class'=>'bootstrap.widgets.TbButtonColumn',
'htmlOptions'=>array('style'=>'width: 50px'),
'afterDelete'=>'function(link,success,data){ if(success) $("#statusMsg").html(data); }'
),
),
));
Из этого файла нас интересует следующий фрагмент описывающий колонку данных:
array(
'type'=>'raw',
'name'=>'columnCourse',
'filter'=>CatalogCourse::getAll(),
'value'=>'CatalogCourse::coursesToStr($data->catalogCourses,$data->clientCourse)',
),
Имени столбика присваиваем имя свойства, созданного в модели Client. В данном случае качестве фильтра используется выпадающий список, значения для которого возвращаются статическим методом CatalogCourse::getAll().
