Skip to content

Instantly share code, notes, and snippets.

@lefuturiste
Created March 23, 2017 20:29
Show Gist options
  • Save lefuturiste/788659e4c3a35618820a9bb10fb05626 to your computer and use it in GitHub Desktop.
Save lefuturiste/788659e4c3a35618820a9bb10fb05626 to your computer and use it in GitHub Desktop.
<?php
/**
* Post @ManyToMany Tag (la relation n'est pas inversée)
*
* Je veux les articles et afficher les tags
* Sans doctrine je ferais la requete de la manière suivante
*
* SELECT * FROM posts LIMIT 10
* SELECT * FROM tag_post LEFT JOIN tag ON tag.id = tag_post.tag_id WHERE tag_post.post_id IN (....) (j'associe les 2 données ensemble après coup dans PHP)
*
**/
//
// N+1
// Marche super, mais génère n+1 requêtes, pas cool
$em->getRepository('AppBundle:Post')->findAll()
// Pas de souci query builder style !
// Marche super, mais si j'ai 10 articles avec 10 tags, ça fait 100 lignes renvoyé par SQL (on a vu mieux mais à la limite ça peut passer)
$this->createQueryBuilder('p')
->join('p.tags', 't')
->select('p, t')
// Maintenant je veux récupérer tous les articles qui appartienne à un tag (et affichés tous les tags associés
// Naturellement je suis tenté d'écrire, mais du coup ça ne cherchera plus les tags associés aux articles, mais seulement le tag correspondant à $tag
$this->createQueryBuilder('p')
->join('p.tags', 't')
->select('p, t')
->where('t.name = :tag')
->setParameter('tag', $tag)
// Si je continue avec doctrine je sens que je vais me lancer dans une subquery (pas tip top niveau performance pour ma pauvre bdd)
// En SQL je ferais
"
SELECT id FROM tag WHERE tag = :tag
SELECT p.* FROM posts p LEFT JOIN tag_post ON post.id = tag_post.post_id WHERE tag_post.tag_id = :tag_id (je récupère les articles associé au tag en question)
SELECT * FROM tag_post LEFT JOIN tag ON tag.id = tag_post.tag_id WHERE tag_post.post_id IN (....) (j'associe les 2 données ensemble après coup dans PHP)
"
// AU FINAL : Mieux vaudrait faire une méthode qui "hydrate" les tags dans une collection de posts sois même ? Un genre d'eager load maison
$this->hydrateTags($posts);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment