Partage
  • Partager sur Facebook
  • Partager sur Twitter

Symfony 5, Querybuilder et relation many to many

Sujet résolu
    13 octobre 2021 à 7:48:22

    Bonjour tout le monde, 

    J'ai un petit souci avec une relation many to many. 

    Un peu de contexte :

    J'ai deux entités : user et bureau

    Un user peut avoir accès à plusieurs bureaux et un bureaux peut accueillir plusieurs users. J'ai une table intermédiaire entre les deux.

    Les ajouts, suppressions, et modifications fonctionnent parfaitement mais je rencontre un problème lorsque j'essaye de récupérer les bureaux d'un user dans un Controller. 

    Dans le Controller j'ai ceci : 

        /**
         * @Route("/all/agence/{id}", name="choix_agence")
         */
        public function choix_agence(AdminBureau $id, Request $request, UserRepository $userRepository)
        {
            $user = $this -> getUser();
            $agences_autorisees = $userRepository->findAgence($user);
        }

    Dans le Repository, ceci : 

        public function findAgence($user): array
        {
            return $this->createQueryBuilder('user')
                ->join('user.agence', 'bureau')
                ->addselect('bureau.nom AS nom')
                ->andWhere('user.id = :user')
                ->setParameter('user', $user)
                ->getQuery()
                ->getResult();
        }

    Quand je dump agences_autorisees, je n'obtiens qu'un seul bureau, alors que je suis sensé en avoir plusieurs. 

    Pourtant quand je test la query générée directement dans la db, j'ai bien les résultats souhaités.

    J'ai plus que probablement mal compris quelque chose et fonctionne donc de travers, est-ce qu'une bonne âme pourrait m'éclairer ? 

    D'avance merci et bonne journée à toutes et tous. 


    • Partager sur Facebook
    • Partager sur Twitter
      13 octobre 2021 à 8:34:18

      Bonjour,

      Pas compris :

      Pourtant quand je test la query générée directement dans la db, j'ai bien les résultats souhaités.

      Sinon tu dois avoir un getter dans l'entité User qui te permet de récupérer la collection de Bureau puisque c'est une ManyToMany bi-directionnelle : cela ne te suffit pas ?

      A+

      • Partager sur Facebook
      • Partager sur Twitter
        13 octobre 2021 à 9:39:06

        Avant tout, un grand merci pour ton aide 😊

        Désolé, j'ai l'art de m'exprimer comme une vache espagnole.

        Quand je dis "la query générée", j'entends par là, la query que je retrouve dans l'onglet Doctrine du Symfony Profiler.

        Voici ce la query que je retrouve 

        SELECT u0_.id AS id_0,
               u0_.created_at AS created_at_1,
               u0_.username AS username_2,
               u0_.firstname AS firstname_3,
               u0_.lastname AS lastname_4,
               u0_.roles AS roles_5,
               u0_.password AS password_6,
               u0_.avatar AS avatar_7,
               a1_.nom AS nom_8,
               u0_.fonction_id AS fonction_id_9
        FROM USER u0_
        INNER JOIN user_admin_bureau u2_ ON u0_.id = u2_.user_id
        INNER JOIN admin_bureau a1_ ON a1_.id = u2_.admin_bureau_id
        WHERE u0_.id = 1

        Sinon pour ceci : 

        "Sinon tu dois avoir un getter dans l'entité User qui te permet de récupérer la collection de Bureau puisque c'est une ManyToMany bi-directionnelle : cela ne te suffit pas ?"

        Alors effectivement, c'était d'ailleurs la première méthode que j'ai testée mais là pour le coup je n'obtiens rien du tout

        Voila ce que j'avais essayé

           public function choix_agence(AdminBureau $id, Request $request, UserRepository $userRepository)
            {
                $session = $request->getSession();
                $agence = $session->get('agence',0);
                $agence = $id;
                $session -> set('agence',$agence);
                $user = $this -> getUser();
                $agences_autorisees = $user->getAgence();
                // $agences_autorisees = $userRepository->findAgence($user);
                dd($agences_autorisees);
                // $referer = filter_var($request->headers->get('referer'), FILTER_SANITIZE_URL);
                // return $this->redirect($referer);
            }



        et le résultat du dump 

        AllController.php on line 26:
        Doctrine\ORM\PersistentCollection {#551 ▼
          -snapshot: []
          -owner: App\Entity\User {#504 ▼
            -id: 5
            -createdAt: DateTime @1634103761 {#502 ▶}
            -username: "test@test.com"
            -firstname: "Shana"
            -lastname: "Pruitt"
            -roles: array:1 [▶]
            -password: "$2y$13$SdwEmzkt9LxJBOJ0Zi.HJOIYQFz9HGz5b7r6NPhDprnTNEv1dLf6S"
            -confirm_password: null
            -fonction: Proxies\__CG__\App\Entity\UserFonction {#501 ▶}
            -avatar: null
            -agence: Doctrine\ORM\PersistentCollection {#551}
          }
          -association: array:20 [ …20]
          -em: Doctrine\ORM\EntityManager {#291 …11}
          -backRefFieldName: "users"
          -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#519 …}
          -isDirty: false
          #collection: Doctrine\Common\Collections\ArrayCollection {#552 ▼
            -elements: []
          }
          #initialized: false
        }



        • Partager sur Facebook
        • Partager sur Twitter
          13 octobre 2021 à 11:06:12

          Une fois que tu as utilisé le getter tu as une collection donc faut boucler dessus pour avoir chaque objet de la collection.

          Doctrine ne récupère pas d'office tous les éléments sauf en lui mettant une option.

          A+

          -
          Edité par monkey3d 13 octobre 2021 à 11:16:12

          • Partager sur Facebook
          • Partager sur Twitter
            13 octobre 2021 à 15:38:57

            Rhooo le boulet que je suis ... 

            C'était pourtant évident 😓

            Un grand merci à toi 

            • Partager sur Facebook
            • Partager sur Twitter

            Symfony 5, Querybuilder et relation many to many

            × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
            × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
            • Editeur
            • Markdown