Show Count Of Child Rows In Cgridview

I’m new to Yii and it seems like an amazing tool, but I’ve been struggling for hours trying to get what would seem to be a simple task accomplished. I have two tables “Unit” and “EquipmentModel”. EquipmentModel is the parent table and “Unit” is the child. In the CGridview, for the EquipmentModels table, I would like to simply display a count of the Units associated with each EquipmentModel. This should take a few minutes in PHP alone, but I just can’t get it to work in Yii. Everything is set up stock. I suspect I’ve left out something obvious to a more experienced Yii coder.

Some snippets from EquipmentModel.php


public function relations() {

        // NOTE: you may need to adjust the relation name and the related

        // class name for the relations automatically generated below.

        return array(

            'units' => array(self::HAS_MANY, 'Unit', 'modelId'),

        );

    }




public function search() {

        // Warning: Please modify the following code to remove attributes that

        // should not be searched.


        $criteria = new CDbCriteria;


        $criteria->compare('id', $this->id);

        $criteria->compare('model', $this->model, true);

        $criteria->compare('description', $this->description, true);


        return new CActiveDataProvider($this, array(

                    'criteria' => $criteria,

                ));

    }

And from the associated admin.php:




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

	'id'=>'equipment-model-grid',

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

	'filter'=>$model,

	'columns'=>array(

		// 'id',

		'model',

		'description',

                [b]array('name' => 'units','value' => 'count($model->units)'),[/b]

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

I get error “htmlspecialchars() expects parameter 1 to be string, array given” I’ve tried all kinds of variations. Please help me before I go bannanas!

Ok, I figured out to use a STAT relation to do this.

from the model for Equipment Models (EquipmentModel.php):


public function relations() {

        // NOTE: you may need to adjust the relation name and the related

        // class name for the relations automatically generated below.

        return array(

            'units' => array(self::HAS_MANY, 'Unit', 'modelId'),

            'unitsCount' => array(self::STAT, 'Unit', 'modelId'),

        );

    }




    /**

     * Retrieves a list of models based on the current search/filter conditions.

     * @return CActiveDataProvider the data provider that can return the models based on the search/filter conditions.

     */

    public function search() {

        // Warning: Please modify the following code to remove attributes that

        // should not be searched.


        $criteria = new CDbCriteria;


        $criteria->compare('id', $this->id);

        $criteria->compare('model', $this->model, true);

        $criteria->compare('description', $this->description, true);


        $criteria->with = array('units' => array('select' => 'serialNum'), 'unitsCount',);


        return new CActiveDataProvider($this, array(

                    'criteria' => $criteria,

                ));

    }

From the associated admin view:


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

	'id'=>'equipment-model-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'model',

		'description',

                'unitsCount',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

I hope this helps someone. Also I’m getting a count of zero showing up in the search field:

3188

it.png

Any idea how to get that out of there?

Hi tommy, welcome to the forum. :D




    array('name' => 'units', 'value' => 'count($data->units)'),

)); ?>



Use $data to access the model instance in each row.

http://www.yiiframework.com/doc/api/1.1/CDataColumn#value-detail

[EDIT]

The suggestion above doesn’t work.

You can’t set ‘name’ to ‘units’.

Correction:




    array('header' => 'Units', 'value' => 'count($data->units)'),



Oh, you’ve solved it yourself. :D

But I hope the reference I linked will surely be a help to you, anyway.

Thanks for your help Softark. I pasted the code you suggested into CGridview columns array, but it still gives me an error:

3189

yiierror.png

Here’s how it looks:


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

	'id'=>'equipment-model-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'model',

		'description',

                array('name' => 'units', 'value' => 'count($data->units)'),

        	array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

And here are the pertaining parts of the model file:


    public function relations() {

        // NOTE: you may need to adjust the relation name and the related

        // class name for the relations automatically generated below.

        return array(

            'units' => array(self::HAS_MANY, 'Unit', 'modelId'),

            //'unitsCount' => array(self::STAT, 'Unit', 'modelId'),

        );

    }


        .............. snipped ............................




    public function search() {

        // Warning: Please modify the following code to remove attributes that

        // should not be searched.


        $criteria = new CDbCriteria;

        $criteria->compare('id', $this->id);

        $criteria->compare('model', $this->model, true);

        $criteria->compare('description', $this->description, true);


        $criteria->with = array('units');  //Added by me.


        return new CActiveDataProvider($this, array(

                    'criteria' => $criteria,

                ));

    }



For some reason it works correctly when I set up a STAT relation. I can live with the STAT, but I’m very curious as to why it won’t work the way you and others have suggested.

Thanks again,

Tommy

I’m curious, too. :(

Do you get the same error when you do it without ‘with’ ?




      //  $criteria->with = array('units');  //Added by me.



Ah, OK. I got it.

My suggestion was wrong.

Try this instead:




    array('header' => 'Units', 'value' => 'count($data->units)'),



The cause of the error is in the inline filter of the grid.

We can not set the relation to ‘name’ when we use the filter: ‘name’ is assumed to be a string, not an array of objects.