我的控制器
$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_a
和tbl_c
通过MANY_MANY
相关于tbl_b
。即tbl_b
有两列链接tbl_a
和tbl_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',
)));
这应该工作。但是不利的是,如果要显示联接表中的许多列,则必须创建许多属性。
更新
很奇怪,所以我尝试从头开始举例。我创建了两个表
ModelA
和ModelB
,如下所示。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
中的ModelB
是ModelA
的外键。然后我举一些例子。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);
}
}
参见模型中的
bAttribute3
和bAttribute4
,我分别将attribute3
表中的attribute4
和ModelB
放在那里。然后在控制器中,我创建了DataProviderpublic 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,我通常也这样做。我认为您可能会错过代码中的某些内容。