Yii Datagrid Relations

Hi,

When I want to add a related column to the datagrid, I simple put say …

address.Postcode

And it will display the Postcode from the address relation.

However if I want to use the Postcode in a filter / sort I have to use a really cumbersome solution.

i.e. put getters / setters in the model, get rid of the "address.Postcode" and replace with a "magic / ghost" property inside the model etc.

Why is displaying it so easy, but when wanting to filter / sort it is hard / cumbersome. I am doing this right or wrong?

Don’t think so because you need a property to hold your search value. If you have no need for searching though, I guess you could just stick to what you previously had and pass that to CSort to still be able to sort:




// cgridview columns

'columns' => array(

	'address.Postcode',

	...,

	...,

}


// Inside your model search method

$sort = new CSort;

$sort->attributes = array(

	'address.Postcode' => array(

		'asc' => 'address.Postcode',

		'desc' => 'address.Postcode DESC',

	),

	...,

	.../

);



Hello James

Perhaps a source dump of your code would help, maybe I can refactor it for you

  1. In the model create property for related attribute:



class Post extends CActiveRecord

{

   public $category_name;

   

   // other stuff

}



  1. Add the property name to the rules() method of model (in the safe/search section):



public function rules()

{

   return array(

      // other stuff

      array('id, category_id, title, body, created_date, category_name', 'safe', 'on'=>'search'),

   );

}



  1. In the search() method of the model add the related model and related property:



public function search()

{

   $criteria=new CDbCriteria;

   $criteria->with = array('category');   // related model

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

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

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

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

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

   $criteria->compare('category.name',$this->category_name,true);  // related property

   

   return new CActiveDataProvider($this, array(

      'criteria'=>$criteria,

      'sort'=>array(

         'defaultOrder' => 't.id desc',

         'attributes' => array(

            'category_name' => array(

               'asc'=>'category.name',

               'desc'=>'category.name DESC',

            ),

            '*',

         ),

      )

   ));

}



  1. In the view file (views/post/admin.php) add related property in column array of CGridView widgets:



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

   // other stuff

   'columns'=>array(

      'id',

      'category_id',

      'title',

      'created_date',

      array(

         'name' => 'category_name',

         'header' => 'Category Name',

         'value' => '$data->category->name',

      ),

   ),

   // other stuff

));