[Miniguida] Come Rendere Ordinabile Una Cgridview Tramite Un Campo Relazionato

A mo’ di block-notes, sono riuscito a capire come fare una cosa e la desidero pubblicare in italiano, così magari da essere utili agli altri, e poi desidero sentire i vostri pareri di certo più professionali del mio

Caso d’esempio:

Tabella Group, model Group

Tabella Utenti, model User, con una colonna groupId che punta a Group.id

1) Aggiungere la relazione ‘Ogni utente (n) appartiene ad un gruppo (1)’

models/User.php




public function relations()

	{

		return array(

		    'group' => array(self::BELONGS_TO, 'groups', 'groupId'),

		);

	}



Una nota: a dispetto di quanto potreste supporre, Yii sembra non avere nessun problema a collegare campi che si chiamao ‘groupId’ invece di ‘group_id’.

2) Aggiungere i criteri di ordinamento

in questo caso seguo la convenzione utilissima e consigliata di chiamare i campo ‘oggetto.campo’

Aggiungere ai ‘criteri’, usati per l’ordinamento e la ricerca, l’oggetto relazionato (‘group’).

Aggiungere anche il criterio di confronto basato sul campo relazionato (group.name’). Si noti che in tutti i casi in cui ci si riferisci alla tabella ‘Groups’ collegati, si usa la parola ‘group’, perché deve coincidere con il nome dell’oggetto impostato nella relation poco fa, che quindi è ‘group’ non ‘groups’ o ‘Groups’

Sempre nella stessa funzione aggiungere i criteri di ordinamento (è l’array ‘sort’); anche qui si usa group.name

Si noti ‘*’: serve per dire al widget di gestire gli altri campi in autonomia, come ha sempre fatto

model/User.php




$criteria=new CDbCriteria; // questa riga c'è già

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

... vari compare ...

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


... 


return new CActiveDataProvider($this, array(

			'criteria'=>$criteria, // questa riga c'è già di sicuro

			'sort'=>array(

				'attributes'=>array(

						'group.name'=>array(

								'asc'=>'group.name',

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

						),

						'*',

				),

			),

		));



3 - Rifiniture

Si noti che perchè tutti fili liscio, nella view admin ci deve essere tra le columns ‘group.name’:

views/users/Admin.php




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

	.. varie cose ... 

	'columns'=>array(

                ... altre colonne ..

		'group.name',

		array(

			'class'=>'CButtonColumn',

		),

	),

)); ?>



Un’altra cosa utile, a questo punto, è definire nel model l’etichetta che verrà usata per ogni riferimento al campo group,name nelle varie view

models/Users.php




	public function attributeLabels() 

	{

		return array(

			'id' => 'ID',

                        ... varie etichette ...

			'group.name' => 'Gruppo di appartenenza',

		);

	}



4 - Questione di eleganza

Potreste modificare la funzione search perchè stia più in ordine, se, come me, non amate gli array di array di array:





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


$sort = new CSort();

$sort->attributes = array(

  'group.name'=>array('asc'=>'group.name',

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

		),

);


return new CActiveDataProvider($this, array(

			'criteria'=>$criteria,

			'sort'=> $sort, 

			));