Single Cdetailview With Related Using A Cgridview

Let’s say I load a view of an author that displays their information using a CDetailView. How could I load a CGridView below it that displays all of their posts? Can somebody point in the right direction with this? Thanks!

Displays one author:


<?php $this->widget('zii.widgets.CDetailView', array(

	'data'=>$model,

	'attributes'=>array(

		'author_id',

                'firstname',

                'lastname',

	),

)); ?>

Displays all related posts:


<?php $this->widget('zii.widgets.grid.CGridView', array(

	'id'=>'author-posts',

	'dataProvider'=>$model->search(),

	'filter'=>$model,

	'columns'=>array(

		'author_id',

		'post_id',

		'content',

		'created',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

if u have relations defined in ur model rules then u can simply use a cgridview below a detailview like this


$this->widget('zii.widgets.grid.CGridView', array(

        'id'=>'author-posts',

        'dataProvider'=>$model->search(),

        'columns'=>array(

                'relation_name.field_name1',

                'relation_name.field_name2',

                array(

                        'class'=>'CButtonColumn',

                ),

        )));

I was thinking that should work. I have relations set and they appear to be working as I can get the related models data from the parent model using a foreach statement. I plopped the CGridView in and never got it to work. I’ll have to review my code again. Thanks for clarifying that it should be working that way.

I’ve change the columns to include the related, but it’s still coming back empty.

Author:


return array(

    'posts' => array(self::HAS_MANY, 'Post', 'author_id'),

);

Post:


return array(

    'author' => array(self::BELONGS_TO, 'Author', 'author_id'),

);

But when I run this code it properly displays the related fields:


foreach ($model->posts as $post) {

	echo $post->content;

}

Any thoughts as to why the CGridView widget is coming back empty in that situation?

I found the solution in another post. I’ll post it here just incase this might help someone else.

http://www.yiiframework.com/forum/index.php/topic/28905-just-learned-cgridview-and-has-many-relation-with-through/


$this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider' => new CArrayDataProvider($model->posts, array('keyField'=>'post_id')),

        'columns' => array(

            'author_id',

            'post_id',

            'content',

            'created',

        ),

    ));

You can use


'dataProvider' => new CArrayDataProvider($model->posts)

inside cgridview.

Just found that solution. Now it doesn’t show the labels properly and isn’t letting me manually assign them.

what is the problem ?

So now I have which shows me all of the related children:


$this->widget('zii.widgets.grid.CGridView', array(

        'dataProvider' => new CArrayDataProvider($model->posts, array('keyField'=>'post_id')),

        'columns' => array(

            'author_id',

            'post_id',

            'content',

            'created',

        ),

    ));

The problem is with cleaning it up and formatting the table a little more. Right now all of the labels read author_id, post_id, content and created. I’d like to manually set them or have them pulled from the labels set in the actual model to Author ID, Post ID, Content and Created.

I tried the following, but it didn’t work:


array('label'=>'Author ID','value'=>'author_id'),

Any thoughts? Thanks!

in your model of posts You shuold have


	public function attributeLabels()

	{

		return array(

                   'author_id' => 'Author ID',

                    ...

		);

	}



This is the place where You should set labels.

But if You like Your way better, you can always:


                    array(

                        'name' => 'Author ID',

                        'value' => '$data["author_id"]',

                    ),

Hmm that seems to the the problem then. My labels are set in the posts model (actually they were set with Gii and haven’t been changed since). Of course I’d prefer to have it read the label from the model because that would be easier to update in the future if needed. Not sure why that isn’t working. It read the labels from the model when I do anything else using that model.

Ah, I was getting name and label mixed up. Cheers for the help. At least now I can move forward ::)