Quantcast
Channel: Yii Framework Forum
Viewing all articles
Browse latest Browse all 18717

Just learned: CGridView and HAS_MANY Relation with Through

$
0
0
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.

Viewing all articles
Browse latest Browse all 18717

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>