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,
));