我的控制器

$criteria = new CDbCriteria();
$criteria -> select = 't.*,b.*';
$criteria -> join = 'INNER JOIN tbl_b b on b.b_id = t.id ';
$criteria -> join .= 'INNER JOIN tbl_c c on c.id = b.c_id';
$criteria -> condition = 'c.id = :cid';
$criteria -> params = array(':cid' => 1);
$dataProvider = new CActiveDataProvider('tbl_a',array(
            'criteria' => $criteria
        ));
$this->render('view',array('dataProvider' => $dataProvider));


我的看法

$this->widget('zii.widgets.grid.CGridView', array(
'id' => 'my-grid',
'dataProvider' => $dataProvider,
'columns' => array(
    'name',
    'description',
    array(
        'header' => 'Column from tbl_b',
        'value' => ''
    ),
        array(
        'class'=>'CButtonColumn',
        'template' => '{view}'
), ),));


我的问题是:如何显示tbl_b中的列值。因为在dataprovider中,我指定了tbl_a,所以虽然我也从tbl_a中选择了所有记录,但它仅从tbl_b中提取数据,而不是从tbl_b中提取数据。

据我了解,它应该显示为$data -> tbl_b -> col_b。但这给出了错误,因为未定义tbl_a.tbl_b。我想知道是什么问题?

Is it something regarding the relation? tbl_atbl_c通过MANY_MANY相关于tbl_b。即tbl_b有两列链接tbl_atbl_c的主要ID。

注意:名称和描述来自tbl_a并显示出来。

请提出建议!

最佳答案

我通常为这种事情做的是在ActiveRecord中创建一个属性。

class A extends CActiveRecord {

    public $bAttribute1

}


当我将表A与表B连接时,我用要创建的属性(在本例中为B)重命名要显示的bAttribute中的字段。

$dataProvider = new CActiveDataProvider('A', array(
    'criteria' => array(
        'select' => array('t.*', 'b.attribute1 AS bAttribute1'),
        'join' => 'JOIN B AS b ON b.joinId = t.id',
    )
));


然后我可以在GridView中显示bAttribute1

$this->widget('zii.widgets.grid.CGridView', array(
    'dataProvider' => $dataProvider,
    'columns' => array(
        'bAttribute1',
)));


这应该工作。但是不利的是,如果要显示联接表中的许多列,则必须创建许多属性。

更新

很奇怪,所以我尝试从头开始举例。我创建了两个表ModelAModelB,如下所示。

CREATE TABLE IF NOT EXISTS `ModelA` (
  `id` int(11) NOT NULL,
  `attribute2` int(11) NOT NULL,
  `attribute3` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

CREATE TABLE IF NOT EXISTS `ModelB` (
  `id` int(11) NOT NULL,
  `aId` int(11) NOT NULL,
  `attribute3` int(11) NOT NULL,
  `attribute4` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;


如您所见,aId中的ModelBModelA的外键。然后我举一些例子。

INSERT INTO `ModelA` (`id`, `attribute2`, `attribute3`) VALUES
(1, 1, 1),
(2, 2, 2);
INSERT INTO `ModelB` (`id`, `aId`, `attribute3`, `attribute4`) VALUES
(1, 1, 10, 100),
(2, 2, 20, 200),
(3, 1, 30, 300),
(4, 1, 40, 400);


因此,ModelA中的条目#1将被ModelB中的3个条目引用,而条目#2将仅具有1。

然后,我创建了模型代码。

class ModelA extends CActiveRecord {
    public $bAttribute3;
    public $bAttribute4;
    public static function model($className = __CLASS__) {
            return parent::model($className);
    }
}


参见模型中的bAttribute3bAttribute4,我分别将attribute3表中的attribute4ModelB放在那里。然后在控制器中,我创建了DataProvider

public function actionIndex(){
    $dataProvider = new CActiveDataProvider('ModelA', array(
        'criteria' => array(
            'select' => array(
                '`t`.*',
                '`b`.`attribute3` AS `bAttribute3`',
                '`b`.`attribute4` AS `bAttribute4`'
            ),
            'join' => 'JOIN `ModelB` AS `b` ON `b`.`aId` = `t`.`id`',
        )
    ));
    $this->render('index', array(
        'dataProvider' => $dataProvider,
    ));
}


而且我认为

$this->widget('zii.widgets.grid.CGridView', array(
    'id' => 'my-grid',
    'dataProvider' => $dataProvider,
    'columns' => array(
        'id',
        'attribute2',
        'attribute3',
        'bAttribute3',
        'bAttribute4',
    ),
));


所以,这就是我所看到的



是你想要的吗?即使对于CActiveDataProvider,我通常也这样做。我认为您可能会错过代码中的某些内容。

09-05 19:22
查看更多