belongsTo et INNER JOIN

13/01/2009, 10:00  |  Tags: , , , ,  |  Publié dans cakephp

Encore une astuce bien cachée dans la documentation de CakePHP… Tellement bien cachée d’ailleurs qu’elle n’y apparaît même pas !
Bref, vous avez une relation belongsTo entre deux modèles, par exemple, vous avez un Concert qui belongsTo une salle de concert (a Venue, in English).
Dans la table venues, il y a un champ city, et je voudrais les prochains concerts dans une ville précise.
Si je me contente d’une relation belongsTo standard, CakePHP va générer lors d’un Model::find(’all’), avec juste une petite condition sur la date des concerts, une requête de ce type :

SELECT `Concert`.*, `Venue`.* FROM `concerts` AS `Concert` LEFT JOIN `venues` AS `Venue` ON (`Concert`.`venue_id` = `Venue`.`id` AND `Venue`.`city` LIKE ‘brest’) WHERE `date` >= ‘2009-01-13′ LIMIT 20

Le problème, c’est que cette requête va retourner toutes les salles de concert de Brest, y compris celle qui n’accueillent pas de concert dans les prochains jours, par le fait de la jointure externe gauche. Voici comment faire :

$conditions= array(’Venue.city LIKE’ => $city);
$this->Concert->unbindModel(array(’belongsTo’ => array(’Venue’)));
$this->Concert->bindModel(array(’belongsTo’ => array(’Venue’ => array(’type’ => ‘inner’))));
$conditions = array(’date >=’ => date(’Y-m-d’));
$order = array (’Concert.date’ => ‘asc’);
$limit = 20;
$params = compact(’contain’, ‘fields’, ‘limit’, ‘conditions’);
$concerts = $this->Concert->find(’all’, $params);

Les lignes intéressantes étant les lignes 2 et 3 : on commence par “défaire” la relation belongsTo définies entre les deux tables au niveau du modèle, avant de la reconstruire avec la clef “type” à “Inner”.
Si vous paginez vos résultats, n’oubliez pas de mettre le deuxième paramètre de Model::unbindModel() et Model::bindModel() à false, sans cela cette nouvelle relation ne s’appliquerait qu’à la requête suivant ces instructions avant d’être remise à zéro pour celle d’après ; or la pagination implique deux requêtes, une qui compte, l’autre qui récupère les résultats.

Si vous avez apprécié cet article, abonnez-vous au fil rss de ce blog pour ne pas louper les prochains.

à lire également

Leave a Response

Archives

Liens au pif

  • photos de bubu
  • blogcatalog
  • mes photos
  • Communauté française CakePHP
  • Cakebaker
  • Google Group CakePHP Fr
  • Mark Story
  • Debuggable
  • pictures of the north country
  • Yahoo Pipe des sites CakePHP FR
  • POPnews
  • Julien Bourgeois
  • Chez Trân
  • Le blog de Pierre
  • Pseudocoder
  • Derniers commentaires

    • Guillaume: Merci pour cette précision, Pierre, je vais aller voir ça.
    • Pierre Martin: Bonjour Guillaume, et merci encore une fois pourle lien vers mon article ! Juste...
    • Guillaume: De loin, on ne voyait pas très bien :)
    • Gabriiiel: Roy nous a remis un trophée… :D
    • Pierre MARTIN: Il y a aussi cet article de teknoid contenant un lien vers un plugin de recherche...
  • Derniers trackbacks