CGridView filters hasMany relationship

Hello,

A have a question regarding why CGridView’s search doesn’t work w/ hasMany relationship.

I built an example database w/ 2 tables.

Student —< Course

STUDENT

  • id

  • name

COURSE

  • id

  • name

  • student_id (FK:w/ STUDENT.id)

      [b]on STUDENT[/b]
    

	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(

			'course' => array(self::HAS_MANY, 'Course', 'student_id'),

		);

	}

    [b]on COURSE[/b]

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(

			'student' => array(self::BELONGS_TO, 'Student ', 'student_id'),

		);

	}

in admin.php of COURSE (//localhost/demo2/course/admin) I have the following code




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

	'id'=>'materia-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'id',

		'name',

		array(

		            'name' => 'student.name',

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

        	),

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

While the information gets shown correctly, the search filter gets omitted for this field.

I tried a different approach to get around this, but I feel it is not the best of solutions.


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

	'id'=>'materia-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'id',

		'name',


		array(

		            'name' => 'student_id',

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

		            'filter' => $model->getStudent() ,

        	),

        	

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

where $model->getStudent is a function that returns a key/value array (IE. array(1 => ‘Joe’, 2 => ‘Tom’, 3=>‘Mary’) ;)

This produces a DropDownList on search (which works fine). Unfortunatly when there is to much data, this is not an elegant solution.

I would like to know a way to have a textbox field w/ search capabilities over Student.name (hasMany relationship).

Thanks

Hi tuolden,

Modify your Course::search() like the following:




	public function search()

	{

		$criteria=new CDbCriteria;

+		$criteria->with = array('student');

		......

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

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

		......

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

+		$criteria->compare('t.name', $this->name, true);

		......

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

+		$criteria->compare('student.name', $this->student_id, true);

		......

	}



[list1]

[*] with ‘student’

[*] disambiguate column names

[*] compare student_id with student.name

[/list]

The view code for the CGridView should be:




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

	'id'=>'materia-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'id',

		'name',

		array(

		        'name' => 'student_id',

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

        	),

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Search boxes of columns with a name that contains a dot, are hidden. You have to work around it.

See http://www.mrsoundless.com/post/2011/05/09/Searching-and-sorting-a-column-from-a-related-table-in-a-CGridView.aspx for step by step instructions

Thanks softark & MrSoundless