It took me a good bit to figure out how to display a relation that goes through a table. I’ll try to document everything I did to get this to work with examples. The tutorials were helpful, but I felt there was just a tad bit of information missing from them. Such as an example of using the returned relational data in a widget that required a CAvtiveDataProvider and in what form this information was returned as.
Database:
kid
-
ID (PK)
-
name
-
age
toyBox
-
ID (PK)
-
kidID (FK -> kid.id)
toy
-
ID (PK)
-
toyBoxID (FK -> toyBox.id)
-
name
My goal is to display a CGridView of all the ‘toys’ that a ‘kid’ had.
Since a ‘kid’ could have many ‘toyBox’ items but a ‘toyBox’ can only belong to one ‘kid’ and ‘toyBox’ can have many ‘toy’ items, but ‘toy’ can only belong to one ‘toyBox’.
So I first added the relation to the Kid model:
//For the Kid model
public function relation(){
return array(
...
'toyBoxes' => array(self::HAS_MANY, 'Kid', array('ID'=>'kidID'),
'toys' => array(self::HAS_MANY, 'Toy', array('ID'=>'toyBoxID'), 'through'=>'toyBoxes'),
...
);
}
For the KidController to display the view:
public function actionView($id) {
$kidModel = Kid::model()->findByPk($id)
// use "$kidModel = $this->loadModel($id);" if you auto generated and this function is available
//render content
$this->render('view', array(
'kidModel' => $kidModel,
));
}
The $kidModel->toys returns an array of Toy Objects with the key of the Toy Objects Primary Key.
Then I had to render the view of the Kid model with the CGridView of all the toys that Kid owned:
<?php
$this->widget('zii.widgets.grid.CGridView', array(
//It is important to note, that if the Table/Model Primary Key is not "id" you have to
//define the CArrayDataProvider's "keyField" with the Primary Key label of that Table/Model.
'dataProvider' => new CArrayDataProvider($kidModel->toys, array('keyField'=>'ID')),
'columns' => array(
'ID',
'name',
),
));
?>
I hope I did not repeat anything and this was helpful.