yii2:如何使用innerjoin在索引(GridView)中添加列

时间:2016-01-26 06:15:20

标签: php mysql yii yii2

我想在GridView :: widget

中添加一列
 <?= GridView::widget([
        'dataProvider' => $dataProvider,
        'filterModel' => $searchModel,
        'columns' => [
            ['class' => 'yii\grid\SerialColumn'],

            'id',
            'owner_id',
            'situation',
            'address',
              [
//            'attribute' => 'address',
            'format' => 'html',
            'label' => 'Image',
            'value' => function ($data) {
                return Html::img('http://iicity.ir/' . $data['address'],
                    ['width' => '60px']);
            },
        ],

            'slideshow_text',

            ['class' => 'yii\grid\ActionColumn'],
        ],
    ]); ?>

我想从另一个表中添加 'owner_id', 的名称 名称在(帐户)表中 表:

id = 1 name = jack

id = 2 name = sara

2 个答案:

答案 0 :(得分:5)

@ suibber的接受了答案:

[
    'attribute' => 'owner_id',
    'value'=>function ($model) {
        $info = Account::findOne(['id' => $model->owner_id]);

        return isset($info->name) ? $info->name : $model->owner_id;
    },
],

有一些问题:

1)构造SQL查询逻辑在视图中公开,因此违反了MVC原则。视图仅用于显示数据。

2)所有相关所有者的数据都是延迟加载的,这意味着查询量乘以表格中显示的行数。

3)如果记录不存在,为什么要显示owner_id?这只是意味着数据已损坏。您甚至不应该检查所有者是否存在,因为逻辑上它应该始终存在,您需要在保存之前执行验证,并且不要使用手动编写的SQL查询(或使用GUI工具)删除数据,以防丢失外键。

4) IDE缺乏自动完成功能。

Yii2解决这个问题的方法显然是使用关系。

将此添加到您的模型中:

<?php

namespace app\models;

use app\models\User;
use yii\db\ActiveRecord;

/**
 * ...
 *
 * @property User $owner
 */
class Picture extends ActiveRecord
{
    /**
     * @return \yii\db\ActiveQuery
     */
    public function getOwner()
    {
        return $this->hasOne(User::className(), ['id' => 'owner_id']);
    }
}

然后在GridView中显示所有者名称:

[
    'attribute' => 'owner_id',
    'value'=>function ($model) {        
        /* @var $model app\models\Picture */

        return $model->owner->name;
    },
],

或者只是:

'owner.name',

优点很明显 - 它的框架方式,代码更短,更易读,可以使用->with('owner') ActiveQuery GridView中的INNER JOIN急切加载数据。

顺便说一句,不需要[ 'attribute' => 'owner_id', 'value'=>function ($model) { /* @var $model app\models\YourModel */ return $model->owner ? $model->owner->name : null; }, ], 。使用单独的SQL查询提取相关数据。如果由于某种原因,所有者是可选的,并且在某些记录中可能不存在,请使用:

type

official docs中详细介绍了处理相关数据,因此这是一个非常基本的问题。首先检查文档。

答案 1 :(得分:1)

use app\models\Account;

...

[
    'attribute' => 'owner_id',
    'value' => function ($model) {
        $info = Account::findOne(['id' => $model->owner_id]);

        return isset($info->name) ? $info->name : $model->owner_id;
    },
],