在GridView中使用关联模型进行搜索和排序

首先我们有两个模型它们直接有关联:

class Author extends CActiveRecord {
...
}

class Post extends CActiveRecord {
...
function relations() {
return array(
'author'=>array( self::BELONGS_TO, 'Author', 'id_author' ),
);
}
...
}


当以网格形式显示所有 Post 时,我们希望显示作者的名字,并且可以通过作者名字中的关键字过滤 Post。提供这些功能的最好解决方式(在我看来)是:

首先需要在 Post 模型中添加一个新的属性,它用来保存搜索的字符串(即要搜索的作者名).也可以使用外键列来实现同样的效果,但是我不喜欢这么用,在搜索条件中保存搜索的字符串而不是外键 id.你还须在搜索条件中将这个新的属性的规则设置为 ​​safe​​。

class Post extends CActiveRecord {
public $author_search;
...
public function rules() {
return array(
...
array( 'xxx,yyy,author_search', 'safe', 'on'=>'search' ),
);
}
}

现在就可以在搜索条件(标准情况-每个模型都要一个 search 方法)中使用这个属性了。同时,我们需要使用条件的 ‘with’ 属性来指定我们的 Post 是通过哪个关系来获取作者(这种方式只需一次数据库查询而不是延迟加载中的多次查询)。

$criteria = new CDbCriteria;
$criteria->with = array( 'author' );
...
$criteria->compare( 'author.username', $this->author_search, true );
...

当我们修改搜索函数时,我们对返回的 CActiveDataProvider 添加一个新的功能

return new CActiveDataProvider( 'Post', array(
'criteria'=>$criteria,
'sort'=>array(
'attributes'=>array(
'author_search'=>array(
'asc'=>'author.username',
'desc'=>'author.username DESC',
),
'*',
),
),
));

配置中排序部分的 ​​attributes​​ 允许我们覆盖默认值。当我们按 ​​author_search​​ 字段排序的时候,它将会按照指定的规则排序,最后的 ​​*​

到现在为止我们已经为我们的网格显示做好了前期准备



$this->widget('zii.widgets.grid.CGridView', array(
'dataProvider'=>$model->search(),
'filter'=>$model,
'columns'=>array(
'title',
'post_time',
array( 'name'=>'author_search', 'value'=>'$data->author->username' ),
array(
'class'=>'CButtonColumn',
),
),
));


这就是所有,我们使用用户名代替用户ID外键列来排序,并且我们可以使用姓名关键字搜索.



本文翻译自外文网站,查看原文请点击: ​​http://www.yiiframework.com/wiki/281/searching-and-sorting-by-related-model-in-cgridview/​