Yii2 GridView实现了对外表的相关表的值的筛选和排序

时间:2016-02-19 16:10:50

标签: gridview yii2 crud gii

我有3张桌子:

CREATE TABLE tabCve
(
    intCveID INTEGER NOT NULL AUTO_INCREMENT,
    strNumber VARCHAR(20) NOT NULL,
    fltScore FLOAT(0),
    strDescription TEXT,
    datImported DATETIME NOT NULL DEFAULT NOW(),
    intCvePhaseID INTEGER,
    intCveTypeID INTEGER,
    PRIMARY KEY (intCveID),
    KEY (intCvePhaseID),
    KEY (intCveTypeID)

) ;


CREATE TABLE tabProgress
(
    intProgressID INTEGER NOT NULL AUTO_INCREMENT,
    intProgressCveID INTEGER NOT NULL,
    intProgressUserID INTEGER NOT NULL,
    intProgressStateID INTEGER NOT NULL,
    intProgressCategoryID INTEGER,
    datCreated DATETIME NOT NULL,
    PRIMARY KEY (intProgressID),
    KEY (intProgressCategoryID),
    KEY (intProgressCveID),
    KEY (intProgressStateID),
    KEY (intProgressUserID)

) ;

CREATE TABLE tabCategory
(
    intCategoryID INTEGER NOT NULL AUTO_INCREMENT,
    strCategory VARCHAR(50) NOT NULL,
    PRIMARY KEY (intCategoryID)

) ;

我使用Gii为tabCve创建了一个CRUD。 我成功地为intCvePhaseID

等引用表中的字段实现了过滤和排序功能

现在我想通过tabCategorytabProgress实施此功能 tabCvetabProgress之间的关系是1比1。

我如何在SearchModel中实现它?

到目前为止我做了什么:

在模型中:

public function getProgress()
{
    return $this->hasOne(TabProgress::className(),['intProgressCveID' => 'intCveID'])->with(['category']);
}   

public function getCategory()
{
    return $this->hasOne(TabCategory::className(),['intCategoryID' => 'intProgressCategoryID']);
}

在SearchModel中:

公共功能搜索($ params) {     $ query = TabCve :: find();

$dataProvider = new ActiveDataProvider([
    'query' => $query,
    'sort'=> ['defaultOrder' => ['strNumber' => 'DESC']],
]);

$query->select(["intCveID","strNumber","fltScore","strDescription","datImported","intCvePhaseID","intCveTypeID",'progress.intProgressCategoryID']);
$query->joinWith("phase");
$query->joinWith("type");
$query->joinWith("progress");
$query->Where(['not like', 'strDescription', '** RESERVED **%', false]);
$query->andWhere(['not like', 'strDescription', '** REJECT **%', false]);
//$query->andWhere(["intProgressID" => null]);

$this->load($params);

if (!$this->validate()) {
    // uncomment the following line if you do not want to return any records when validation fails
    // $query->where('0=1');
    return $dataProvider;
}

$query->andFilterWhere([
    'intCveID' => $this->intCveID,
    'fltScore' => $this->fltScore,
    'datImported' => $this->datImported,
]);

$query->andFilterWhere(['like', 'strNumber', $this->strNumber])
    ->andFilterWhere(['like', 'strDescription', $this->strDescription])
    ->andFilterWhere(['like','tabPhase.strPhase', $this->intCvePhaseID])
    ->andFilterWhere(['like','datImported',$this->datImported])
    ->andFilterWhere(['like','tabType.strType', $this->intCveTypeID])
    ->andFilterWhere(['like','tabProgress.tabCategory.strCategory', $this->intCveTypeID])
    ;
return $dataProvider;
}

我如何实现以下行中的字段:

$query->select(["intCveID","strNumber","fltScore","strDescription","datImported","intCvePhaseID","intCveTypeID",'progress.intProgressCategoryID']);

->andFilterWhere(['like','tabProgress.tabCategory.strCategory', $this->intCveTypeID])

2 个答案:

答案 0 :(得分:1)

在你的seachModel中,你需要使用public var for filter ..

不需要选择因为这是由find提供的..并且最好重新排列下面的代码

$query->select(["intCveID","strNumber","fltScore","strDescription","datImported","intCvePhaseID","intCveTypeID",'progress.intProgressCategoryID']);
$query->joinWith("phase");
$query->joinWith("type");
$query->joinWith("progress");
$query->Where(['not like', 'strDescription', '** RESERVED **%', false]);
$query->andWhere(['not like', 'strDescription', '** REJECT **%', false]);

以本文档中建议的另一种方式

http://www.yiiframework.com/wiki/621/filter-sort-by-calculated-related-fields-in-gridview-yii-2-0/

http://www.yiiframework.com/wiki/653/displaying-sorting-and-filtering-model-relations-on-a-gridview/

对于

->andFilterWhere(['like','tabProgress.tabCategory.strCategory', 
        $this->intCveTypeID])

上面链接中提供的示例建议使用getter来检索所需的列,并在andFilterWhere中使用此getter

这样:

在您的模型中,您已经有了

public function getCategory()
{
    return $this->hasOne(TabCategory::className(),
     ['intCategoryID' =>   'intProgressCategoryID']);
}

然后你可以为strCategory

建立一个getter
public function getStr_category() {
    return $this->category->strCategory;
}

此时您可以使用

检索modelSearch中的数据
->andFilterWhere(['like','str_category', $this->intCveTypeID])

答案 1 :(得分:-1)

在以下位置访问有关此问题的完整教程:

http://www.yiiframework.com/wiki/851/yii2-gridview-sorting-and-searching-with-a-junction-table-column-many-to-many-relationship/

根据本教程,你应该: 1.在搜索模型中将您的相关表属性设置为public,如下所示:

public $groupname;

2。包含规则中的属性:

    public function rules() {
        return [
            [['id', 'gender', 'status', 'sentstatus'], 'integer'],
            [['groupname', 'addeddate', 'updateddate'], 'safe'],
        ];
    }
  1. 将默认查询更改为搜索模型中函数search()中的以下代码:

    public function search($params) {
    $query = Contacts::find()->innerJoinWith('groups', true);
    
    
  2. 并在andfilterwhere中添加想要的属性。像这样:

    $query->andFilterWhere(['like', 'firstname', $this->firstname])
                   ... 
                    ->andFilterWhere(['like', 'groupname', $this->groupname]);
    
  3. 视图类和Gridview中,您想要的列应该是这样的:

    'columns' => [
                    ...
                [
                    'attribute' => 'tags',
                    'format' => 'raw',
                    'value' => function ($data) {
                        $groups= '';
                        foreach ($data->groups as $group) {
                            $groups .= '<a href="/group/' . $group->id . '">' .
                            $group->group_name . '</a> | ';
                        }
                        return $groups;
             },
            'filter' => ArrayHelper::map(group::find()->asArray()->all(), 'group_name','group_name'),
                    ],
    

    如果表关系为hasOne(),您应该阅读本教程:

    http://www.yiiframework.com/wiki/653/displaying-sorting-and-filtering-model-relations-on-a-gridview/