2

私のコントローラー

$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_atbl_btbl_b

私が学んだことから、それはとして表示されるはず$data -> tbl_b -> col_bです。しかし、これはtbl_a.tbl_b定義されていないのでエラーを与えています。何が問題なのかしら?

Is it something regarding the relation? tbl_aとはを介しtbl_cて関連付けられています。つまり、とのプライマリIDをリンクする2つの列があります。MANY_MANYtbl_btbl_btbl_atbl_c

注:名前と説明はtbl_aからのものであり、表示されます。

提案してください!

4

1 に答える 1

7

この種のことのために私が通常行うことは、ActiveRecordで属性を作成することです。

class A extends CActiveRecord {

    public $bAttribute1

}

Aテーブルをテーブルと結合するとき、表示したいBフィールドの名前を、作成した属性(この場合は)で変更します。BbAttribute

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

次にbAttribute1、GridViewにを表示できます。

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

これは機能しているはずです。ただし、結合されたテーブルから多くの列を表示する場合は、多くの属性を作成する必要があるという欠点があります。

アップデート

変なので、一から例を作ってみました。以下のように2つのテーブルを作成しまし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;

ご覧のとおり、aIdinModelBはへの外部キー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);

したがって、エントリ#1ModelAはの3つのエントリによって参照されますがModelB、エントリ#2は1つしかありません。

次に、モデルコードを作成しました。

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

モデルのbAttribute3とを参照してください。それぞれ、テーブルからとを配置します。次に、コントローラーでDataProviderを作成しましたbAttribute4attribute3attribute4ModelB

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',
    ),
));

だから、これが私が見るものです

Imgur

それはあなたが望むものですか?私は通常、CActiveDataProviderに対してもこのようにします。私はあなたがあなたのコードで何かを見逃すかもしれないと思います。

于 2012-06-21T22:25:47.110 に答える