CGridView, name, 3 depths

Hi All

A lot of forum posts deal (moreorless) to this topic, but I can’t fnd solution to my problem.

I have a CGridView which is intended to display data of a specific model and data of others models (linked by belongsTo or Many, relationships)

I have a Marque (ex Volvo, Chrysler) which has several Modeles (V50 for Volvo for instance) And a Modele has several Version (A V50 could be 1.6l or 2.0l …)

I have this code:


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

	'id'=>'admin-version-grid',

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

	'filter'=>$model,

	'columns'=>array(

		'id',

		'nom',

          array(//here is my problem, I have the name of the Marque displayed => OK But I can't perform any filter on it

              'header'=>'Marque',

              'name'=>'modele.marque.nom',

              'sortable'=>true,

              //'value'=>'AdminMarque::model()->findByPk(AdminModele::model()->findByPk($data->modele_id)->marque_id)->nom',

              //'filter'=>CHtml::listData(AdminMarque::model()->findAll(), 'id', 'nom'),

          ),

          array(

              'name'=>'modele_id',

              'value'=>'AdminMotorisation::model()->findByPk($data->modele_id)->nom',

          ),

          array(

              'name'=>'motorisation_id',

              'value'=>'AdminMotorisation::model()->findByPk($data->motorisation_id)->nom',

          ),

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>

I attached an image to have a look.

I also try with the commented line (that I de commented)


 //'value'=>'AdminMarque::model()->findByPk(AdminModele::model()->findByPk($data->modele_id)->marque_id)->nom',

              //'filter'=>CHtml::listData(AdminMarque::model()->findAll(), 'id', 'nom'),

But it is still the same problem …

I turn crazy…

Does someone have some hints ?

Thanks

The thing that I do not understand is that I can get value of “Marque” (trademark)but I’m unable to build a filter for this field…

More Or less similar topics deals with table "A" and table "B" and how create filter/sort values in a CGridView

In my case it is "A" which has several "B" which has several "C" and building a CgridView

I can get data from "A"(A.nom) due to relation b.a (b relation declared in C model, and a relation declared in B model)

But impossible to build a filter on A.nom values

Is it a strange design ? (I mean shall I build another table (I doubt but …)) ?

Thanks

Use a function for filter:




array(

       'header'=>'Marque',

       'name'=>'modele.marque.nom',

       'value'=>'AdminMarque::model()->findByPk(AdminModele::model()->findByPk($data->modele_id)->marque_id)->nom',

       'filter'=>getMarqueFilter()

),



And the function:




function getMarqueFilter() {

	$marque_arr = array();

	foreach(AdminMarque::model()->findAllByAttributes(array('whatever'=>'whatever')) as $marque) { //obviously change this depending on the model/attributes you want to search

		$marque_arr[$marque->nom] = $marque->nom;

	}

	return $marque_arr;

}



Thanks Clint,

1/ I declare public static the filter function in AdminMarque model

2/ the $marque_arr contains BMW and Audi for instance, but the CGridView stays without filter box on this Marque field

And a hint

when


'name'=>'modele.marque.nom',

is given in a Column it is not necessary (and it seems to be the non good way to do) to specifiy the ‘value’ field


'value'=>'AdminMarque::model()->findByPk(AdminModele::model()->findByPk($data->modele_id)->marque_id)->nom',

       'filter'=>getMarqueFilter()

By declaring


'name'=>'modele.marque.nom',

data are populated into the CGridView

But however my problem still exists. I can’t have a filter on my data when modele.marque.nom …

I modified my Search() method in order to provide data for the CGridView but I have an SQL error saying that column modele.marque.nom doesn’t exist.

in my Relation


return array(

              'modele'       =>array(self::BELONGS_TO,'AdminModele','modele_id'),

              'motorisation' =>array(self::BELONGS_TO,'AdminMotorisation','motorisation_id'),

		);


	public function searchG()

	{

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

		// should not be searched.

		$criteria=new CDbCriteria;


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

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

          $criteria->with=array('modele','motorisation','modele.marque');

          $criteria->addSearchCondition('modele.nom',$this->modele_id,true); // Work well

          $criteria->addSearchCondition('motorisation.nom',$this->motorisation_id,true); // Work well

          // La marque

          $criteria->addSearchCondition('modele.marque.nom',$this->marque_nom,true);// Generate the error...


          $data = new CActiveDataProvider(get_class($this), array(

			'criteria'=>$criteria));

          return $data;


	}

marque_nom is a public variable that I added in my model because it seems to be a way to collect data from the second table (modele.marque)

Does someone already have this configuration of searching, a.b.c (modele.marque.nom)

---- This is the SQL command


SELECT COUNT(DISTINCT `t`.`id`) FROM `tbl_version` `t`  

LEFT OUTER JOIN `tbl_modele` `modele` ON (`t`.`modele_id`=`modele`.`id`)  

LEFT OUTER JOIN `tbl_marque` `marque` ON (`modele`.`marque_id`=`marque`.`id`)  

LEFT OUTER JOIN `tbl_motorisation` `motorisation` ON (`t`.`motorisation_id`=`motorisation`.`id`)  

WHERE (modele.marque.nom LIKE :ycp0)

Problem is that modele.marque.nom is a valid column but Yii generates an Exception

The good deal would be to have


WHERE (marque.nom LIKE :ycp0)

OK I found (But I would be unable to say why it works…seems me like Voodoo

In my Search I replace


$criteria->addSearchCondition('modele.marque.nom',$this->marque_nom,true);

By


$criteria->addSearchCondition('marque.nom',$this->marque_nom,true);

And I obtain my filter on my data

Thing that I can’t understand is how the system knows the relation marque without modele.marque because in the model just exists ‘modele’ relation

I wish I could explain more but I am still learning as well, a lot of this stuff does seem like Voodoo, in particular with the CGridView.