Il titolo è un po’ contorto, ma non sono riuscito a trovare di meglio.
L’esigenza nasce quando voglio ordinare il risultato di una query che vede interessati vari Model utilizzando un determinato campo per l’ordinamento.
Faccio l’esempio: ho i seguenti model e le seguenti relazioni.
Continent hasMany Country
Country hasMany News
Il modello Continent ha un campo ‘order’ che serve a mantenere un determinato ordine di presentazione per i continenti.
Voglio ottenere una lista di News ordinate per Continent.order.
Poichè il model News ha molte relazioni con altri model (Tag, Area, Comment, ecc. ecc. ), utilizzo il behavior Containable.
A questo punto non è sufficente impostare l’elemento ‘order’ a ‘Continent.order ASC’, perchè la query restituisce un errore. Infatti CakePHP esegue prima una query per ricavare l’elenco delle News e per ogni News ricavata esegue una successiva query per determinare il continente relativo al country.
// $this->Continent->find('all', array('order' => 'Continent.name')) // Restituisce un errore nell query SQL //
SOLUZIONI
Una soluzione generica che risolve ampiamente il problema è impiegare questo behavior suggeritomi da fzanardo nel forum, ma che non ho personalmente provato.
Una soluzione light invece è la seguente:
// estraggo gli di dei continenti ordinati in base al campo 'order' $continents = array_keys($this->News->Country->Continent->find('list',array('fields'=>array('id','order'),'recursive'=>-1,'order'=>'order'))); $lista = $this->News->find('all',array( 'conditions'=>$conditions, 'contain'=>array( 'Area', 'Country'=>array('Continent'), ), 'order' => array('FIELD(Country.continent_id,'.implode(',',$continents).')')
ORDER BY FIELD(Country.continent_id, 1,4,3,6,5,2) sarà l’impostazione del’ordine che consentirà di ottenere l’ordine voluto, mantenendo la query leggera.
Riferimento: http://cakebaker.42dh.com/2008/06/10/order-by-field/