基于关系值的PHP、Yi2 GridView过滤

基于关系值的PHP、Yi2 GridView过滤,php,entity-relationship,yii2,Php,Entity Relationship,Yii2,以下是: 我希望能够过滤关系数据的GridView列。这就是我的意思: 我有两个表,TableA和TableB。两者都有使用Gii生成的相应模型TableA有一个外键指向TableB中的值,如下所示: TableA attrA1, attrA2, attrA3, TableB.attrB1 TableB attrB1, attrB2, attrB3 public function search($params){ $query = TableA::find(); $data

以下是:

我希望能够过滤关系数据的
GridView
列。这就是我的意思:

我有两个表,
TableA
TableB
。两者都有使用Gii生成的相应模型
TableA
有一个外键指向
TableB
中的值,如下所示:

TableA
attrA1, attrA2, attrA3, TableB.attrB1

TableB
attrB1, attrB2, attrB3
public function search($params){
    $query = TableA::find();
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

    $this->addCondition($query, 'attrA2');
    $this->addCondition($query, 'attrA2', true);
    $this->addCondition($query, 'attrA3');
    $this->addCondition($query, 'attrA3', true);

    return $dataProvider;
}
attrA1和attrB1是它们对应表的主键

现在,我有了一个Yii2
GridView
attrA2
attrA3
attrB2
。我在
attrA2
attrA3
上有一个工作过滤器,这样我就可以搜索列值。我对这两列也有一个有效的排序——只需单击列标题。我也希望能够在
attrB2
上添加此过滤和排序

我的
表格搜索
模型如下所示:

TableA
attrA1, attrA2, attrA3, TableB.attrB1

TableB
attrB1, attrB2, attrB3
public function search($params){
    $query = TableA::find();
    $dataProvider = new ActiveDataProvider([
        'query' => $query,
    ]);

    if (!($this->load($params) && $this->validate())) {
        return $dataProvider;
    }

    $this->addCondition($query, 'attrA2');
    $this->addCondition($query, 'attrA2', true);
    $this->addCondition($query, 'attrA3');
    $this->addCondition($query, 'attrA3', true);

    return $dataProvider;
}
在我的
表格A
模型中,我设置了如下相关值

    public $relationalValue;

public function afterFind(){
    $b = TableB::find(['attrB1' => $this->attrB1]);
    $this->relationalValue = $b->relationalValue;
}

虽然这可能不是最好的方法。我想我必须在搜索函数的某个地方使用$relationalValue,但我不确定如何使用。同样,我也希望能够按此列进行排序-就像我可以通过单击标题链接对
attrA2
AttrA3
进行排序一样。任何帮助都将不胜感激。谢谢。

这是基于中的描述。SearchModel的基本代码来自Gii代码生成器。这还假设$This->TableB是使用
hasOne()
hasMany()
关系设置的。看这个

1。设置搜索模型

表格搜索中
模型添加:

public function attributes()
{
    // add related fields to searchable attributes
    return array_merge(parent::attributes(), ['TableB.attrB1']);
}

public function rules() 
{
    return [
        /* your other rules */
        [['TableB.attrB1'], 'safe']
    ];
}
然后在
表格搜索->搜索()
添加(在
$this->load()之前):

然后实际搜索数据(在
$this->load()下面):

2。配置
GridView

添加到您的视图中:

echo GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        /* Other columns */
       'TableB1.attrB1',
        /* Other columns */        
     ]
]);

我也被这个问题困住了,我的解决方案完全不同。我有两个简单的模型:

书籍:

作者:

class Author extends ActiveRecord
{

    public static function tableName()
    {
        return 'authors';
    }

    public function getBooks()
    {
        return $this->hasMany(Book::className(), ['author_id' => 'id']);
    }
但我的搜索逻辑是不同的。我也没有发现如何在不创建额外字段的情况下实现搜索
author\u first\u name
。这就是我的解决方案:

class BookSearch extends Model
{
    public $id;
    public $title;
    public $author_first_name;

    public function rules()
    {
        return [
            [['id', 'author_id'], 'integer'],
            [['title', 'author_first_name'], 'safe'],
        ];
    }

    public function search($params)
    {
        $query = Book::find()->joinWith(['author' => function($query) { $query->from(['author' => 'authors']);}]);
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
            'pagination' => array('pageSize' => 50),
            'sort'=>[
                'attributes'=>[
                    'author_first_name'=>[
                        'asc' => ['author.first_name' => SORT_ASC],
                        'desc' => ['author.first_name' => SORT_DESC],
                    ]
                ]
            ]
        ]);

        if (!($this->load($params) && $this->validate())) {
            return $dataProvider;
        }
        ....
        $query->andWhere(['like', 'author.first_name', $this->author_first_name]);
        return $dataProvider;
    }
}
这用于创建表别名:
function($query){$query->from(['author'=>'authors']);}

GridView代码为:

<?php echo GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [
        [
            'attribute' => 'id',
            'filter' => false,
        ],
        [
            'attribute' => 'title',
        ],
        [
            'attribute' => 'author_first_name',
            'value' => function ($model) {
                    if ($model->author) {
                        $model->author->getFullName();
                    } else {
                        return '';
                    }
                },
            'filter' => true,
        ],
        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>


我将感谢任何批评和建议

在Yii 2.0中,按列过滤gridview非常简单。请将筛选器属性添加到具有查找值的gridview列,如下所示:

[
        "class" => yii\grid\DataColumn::className(),
        "attribute" => "status_id",
        'filter' => ArrayHelper::map(Status::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
        "value" => function($model){
            if ($rel = $model->getStatus()->one()) {
                return yii\helpers\Html::a($rel->name,["crud/status/view", 'id' => $rel->id,],["data-pjax"=>0]);
            } else {
                return '';
            }
        },
        "format" => "raw",
], 

您是否可以更新您的问题,使searchModel反映对框架的最新更改应该是
$query->joinWith(['TableB'])非常好的答案,谢谢,但随着Yi2的发展,我已经将“解决方案”重新分配到了更简单的答案上。干杯。我添加了这个来忽略字符大小写:
$query->andFilterWhere(['like','LOWER(TableB.attrB1'),strtolower($this->getAttribute('TableB.attrB1')))只是刚刚看到这个,一年过去了,自从我问起已经两年了。这是一个简洁的答案,也是迄今为止最简单的解决方案。谢谢。这很好,对我来说很有用,但都会导致DropDownList,如何像更多过滤器文本框一样改变ajax文本框???
[
        "class" => yii\grid\DataColumn::className(),
        "attribute" => "status_id",
        'filter' => ArrayHelper::map(Status::find()->orderBy('name')->asArray()->all(), 'id', 'name'),
        "value" => function($model){
            if ($rel = $model->getStatus()->one()) {
                return yii\helpers\Html::a($rel->name,["crud/status/view", 'id' => $rel->id,],["data-pjax"=>0]);
            } else {
                return '';
            }
        },
        "format" => "raw",
],