Related Model In Cgridview Not Working

I am trying to display a related model attribute ‘assignee’ in my CGridView according to CGriedView Related Model, but I get the error message “Property “Bugs.assignee” is not defined.”.

I have added the property assignee to the model Bugs as

@property string $assignee

In my rules I have the following:


	public function rules()

	{

		// NOTE: you should only define rules for those attributes that

		// will receive user inputs.

		return array(

			array('assigned_to, bug_file_loc, bug_severity, bug_status, delta_ts, short_desc, op_sys, priority, product_id, rep_platform, reporter, version, component_id, status_whiteboard, everconfirmed, cf_comment', 'required'),

			array('assigned_to, product_id, reporter, component_id, qa_contact, everconfirmed, reporter_accessible, cclist_accessible, votes', 'numerical', 'integerOnly'=>true),

			array('bug_severity, bug_status, op_sys, priority, rep_platform, version, resolution, target_milestone, cf_satisfaction', 'length', 'max'=>64),

			array('short_desc', 'length', 'max'=>255),

			array('estimated_time, remaining_time', 'length', 'max'=>7),

			array('alias', 'length', 'max'=>20),

			array('creation_ts, lastdiffed, deadline', 'safe'),

			// The following rule is used by search().

			// Please remove those attributes that should not be searched.

			array('bug_id, assigned_to, assignee, bug_file_loc, bug_severity, bug_status, creation_ts, delta_ts, short_desc, op_sys, priority, product_id, rep_platform, reporter, version, component_id, resolution, target_milestone, qa_contact, status_whiteboard, lastdiffed, everconfirmed, reporter_accessible, cclist_accessible, estimated_time, remaining_time, deadline, alias, votes, cf_satisfaction, cf_comment', 'safe', 'on'=>'search'),

		);

	}

In my criteria object I have the following:


$criteria=new CDbCriteria;

		$criteria->with = array('assignedTo');


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

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

  		$criteria->compare('assignedTo.login_name', $this->assignee, true);

What am I missing?

you need to declare a association under relations method.


....

'assignee'=>array(self::BELONGS_TO, 'Assignee', 'assignee_id')

....

Hi my problem was I didn’t have $assignee added as member variable to the model.

I created only the phpdoc @property and thought it would suffice.

I am just going by the example of CGridView related model.

Do you have a different approach alirz23?




/* @property string $assignee */



It’s a comment and PHP takes no count of it, but only some clever IDEs. :)

Standard properties of a CActiveRecord which stand for columns of a table, are actually declared deep inside the CActiveRecord code. Gii generates property comments, but they are for IDEs and programmers.

  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

));



This is really tedious.

What if I have 50 columns or 100 in a related model?

Do I really want to copy & paste all of them in the parent model?

What if I have several related models?

There has to be a better way than that. The related models exist and know their responsibilities. I should not have to copy stuff over.

I agree, that is quite some work to do for a lot of columns.

A better way to do that is to use myRelatedSearchBehavior extension. It is not entirely automatic, but avoids a lot of coding and offers most of the functionnality "automagically".

I think I have a solution, that allows us to use only the related model and avoids the copy & paste. I’ll post it soon after running a few tests.