IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

Problème QueryBuilder ManyToMany complexe


Sujet :

Symfony PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Service public

    Informations forums :
    Inscription : Décembre 2005
    Messages : 109
    Points : 88
    Points
    88
    Par défaut Problème QueryBuilder ManyToMany complexe
    Bonjour a tous,

    J'ai un soucis sur Symfony2, plus précisément sur une requête a réaliser et je souhaiterai le faire avec le QueryBuilder. Pour faire simple j'ai une relation ManyToMany entre un Objet "Article" et un autre "Tag". Cette relation est déclarée dans "Article".

    Ce que je souhaite:

    Je veux faire une requête qui me donnera en retour un tableau ou un objet ou chaque ligne contient l'id et le titre du tag ainsi que le nombres d'articles dans lequel ce tag est utilisé, ceci pour chaque tag. En SQL ca donnerai exactement ceci: (en considérant la table article pour l'objet article / la table tag pour l'objet tag et la table article_tag qui établit la relation au niveau SQL.

    Code sql : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    SELECT 
    	t.id,
    	t.titre,
    	COUNT(t.id) AS nbTags
    FROM
    	tag AS t,
    	article_tag AS r
    WHERE 
    	t.id = r.tag_id
    GROUP BY t.id 
    ORDER BY nbTags DESC

    Je ne suis vraiment pas à l'aise avec le QueryBuilder et n'arrive pas du tout a effectuer la requête, j'ai vaguement tenté (depuis le repository de mon objet Tag comme suit (mais c'est vraiment perdu la -_-) et même en cherchant sur le web je n'arrive pas a comprendre comment adapter les solutions fournies a certains problème vers le mien.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class TagRepository extends EntityRepository
    {
    	public function getTagsByPriority(){
    		$req = $this->getEntityManager()->createQueryBuilder('t')
    				   ->join('CodeyourwebArticleBundle:Article','a')
    				   ->addSelect('COUNT(t) AS nbTags')
    				   ->groupBy('t.id')
    				   ->orderBy('nbTags', 'DESC');
     
    		return $req->getQuery()->getResult();
    	}
    }
    Merci d'avance de me montrer comment on fait pour retourner un tableau avec l'id et le titre de chaque tag ainsi que le nombres d'articles dans lequel il est utilisé.
    Mon blog technique: www.codeyourweb.org
    HTML5 / CSS3 / JS – Intégration des technologies du web a destination des nouvelles plateformes et nouveaux usages d'internet

  2. #2
    Membre expérimenté Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Points : 1 310
    Points
    1 310
    Par défaut
    Hello,

    Le problème vient du fait que tu réfléchis encore en mode SQL. Si tu utilises Doctrine (ou de manière plus large : un ORM), tu n'es plus censé réfléchir au SQL, tu réfléchis en termes d'objets, de collections, etc.

    Là typiquement tu veux un objet article, et tu veux savoir quelle taille a sa collection de tags.

    L'objet article tu peux l'obtenir très simplement à l'aide de l'entityManager et des méthodes déjà existantes. Ensuite, si ton modèle est bien fait, ton objet article il doit avoir un attribut $tags qui représente la collection d'objets Tag. Ta collection selon toute logique est de type ArrayCollection (classe de Doctrine), et cette classe possède tout un tas de méthode, dont la méthode count qui te permet de compter le nombre d'objet présents dans une collection.

    En résumé ça donne quelque chose d'assez simple, sans même passer par SQL.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $article = $entityManager->getRepository('your_article_repository')->find($id);
    $tagsNb = $article->getTags()->count();
    Admettons que tu veuilles récupérer tous les articles et afficher le count dans le twig :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    // PHP
    $articles = $entityManager->getRepository('your_article_repository')->getArticlesWithTags();
     
    // Repository
    public function getArticlesWithTags()
    {
        $qb = $this->createQueryBuilder('a');
        $qb
            ->addSelect('t')
            ->join('a.tags', 't')
        ;
     
        return $qb->getQuery()->getResult();
    }
     
    // Twig
    {% for article in articles %}
        {{ article.tags.count }}
    {% endfor %}
    On aurait pu récupérer les article en faisant un simple $articles = $entityManager->getRepository('your_article_repository')->findAll(); mais le problème est que Doctrine n'aurait pas chargé tout de suite tes collections de tags et aurait fait la requête pour la rajouter à l'intérieur de ta boucle (lazy-loading), ce qui aurait multiplié les requêtes.

    [EDIT] Je viens de me rendre compte que j'ai fait exactement l'inverse de ce que tu demandais. Ca ne change pas grand chose : tu peux interchanger vu que c'est une relation ManyToMany.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    $tag = $entityManager->getRepository('your_tag_repository')->find($id);
    $articlesNb = $tag->getArticles()->count();
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    // PHP
    $tags = $entityManager->getRepository('your_tag_repository')->getTagsWithArticles();
     
    // Repository
    public function getTagsWithArticles()
    {
        $qb = $this->createQueryBuilder('t');
        $qb
            ->addSelect('a')
            ->join('t.articles', 'a')
        ;
     
        return $qb->getQuery()->getResult();
    }
     
    // Twig
    {% for tag in tags %}
        {{ tag.articles.count }}
    {% endfor %}
    Bon courage ++

Discussions similaires

  1. Utilisation du pivot : problème de requête "complexe"
    Par Kropernic dans le forum Développement
    Réponses: 12
    Dernier message: 27/01/2011, 11h44
  2. Problème @OneToMany @ManyToMany etc
    Par BIL88 dans le forum Seam
    Réponses: 3
    Dernier message: 20/12/2010, 22h33
  3. Problème de jointures complexes
    Par Cryos dans le forum Développement
    Réponses: 6
    Dernier message: 29/04/2010, 15h03
  4. Réponses: 2
    Dernier message: 11/07/2008, 14h44
  5. [EJB & WS] Problème Mapping Types complexes
    Par Mehdibr dans le forum Services Web
    Réponses: 3
    Dernier message: 04/07/2007, 14h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo