Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Symfony 4] générer une table avec 2 relations MtM

ManyToMany

Sujet résolu
    26 mars 2020 à 10:57:04

    Bonjour
    Je vais vous poser une question, peut-être bête.
    J'ai crée une relation ManyToMany pour les entités roles et personnes. Cela génère une nouvelle table named as role_people_season. Cela fonctionne bien.
    Et je souhaiterais créer une autre ManyToMany pour les entités saisons et personnes. 
    Serait-il possible de rajouter un champ dans la même table role_people_season ?
    Cette table devrait donc contenir 3 champs role_id, people_id, seasons_id
    Plusieurs joueurs ont plusieurs saisons
    plusieurs saisons ont plusieurs joueurs
    plusieurs joueurs ont plusieurs roles
    plusieurs roles ont plusieurs joueurs
    L'erreur me retourne suivant:
    The table with name 'sf4.people_role_season' already exists.
    Je vous remercie beaucoup de vos réponses.
    Bonne journée
    Restez chez vous
            /**
             * @ORM\ManyToMany(targetEntity="App\Entity\Roles", inversedBy="people")
             * ORM\JoinTable(name="people_role",
             *      joinColumns={@ORM\JoinColumn(name="people_id", referencedColumnName="id")},
             *      inverseJoinColumns={@ORM\JoinColumn(name="roles_id", referencedColumnName="id")}
             *      )
             * @ORM\JoinTable(name="people_role_season")
             */
            private $role;
    
            /**
             * @ORM\ManyToMany(targetEntity="App\Entity\Seasons", inversedBy="people")
             * ORM\JoinTable(name="people_season",
             *      joinColumns={@ORM\JoinColumn(name="people_id", referencedColumnName="id")},
             *      inverseJoinColumns={@ORM\JoinColumn(name="seasons_id", referencedColumnName="id")}
             *      )
             * @ORM\JoinTable(name="people_role_season")
             */
            private $season;

    -
    Edité par cyphos 26 mars 2020 à 10:58:17

    • Partager sur Facebook
    • Partager sur Twitter
      26 mars 2020 à 11:35:36

      Bonjour.

      Il te faut faire une migration, mais dans laquelle tu ne fais pas une création de table, mais une modification de table.

      Par contre fais attention dans ton explication concernant la relation entre les tables, car ça n'a pas de sens ce que tu expliques dans ton message :

      • des joueurs n'ont pas des saisons, des saisons n'ont pas des joueurs et les roles n'ont pas des joueurs

      Il n'y a que la troisième dont la formulation est correcte.

      • Partager sur Facebook
      • Partager sur Twitter

      Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

        26 mars 2020 à 11:54:55

        Bonjour Lartak

        Désolé pour mon message qui ne vous semble pas très clair. Désolé, je ne suis pas très écrivain mais plutôt pragmatique. C'est pourquoi je préférerais montrer le code. 

        Bref, j'essaie de comprendre votre explication concernant la modification de table.

        vous voulez dire ci-dessous ?

        ALTER TABLE nom_table
        ADD nom_colonne type_donnees

        pouvez-vous m'expliquer ceci? qu'est ce qui est troisième?

        Il n'y a que la troisième dont la formulation est correcte.

        encore merci à vous

        -
        Edité par cyphos 26 mars 2020 à 11:58:01

        • Partager sur Facebook
        • Partager sur Twitter
          26 mars 2020 à 11:58:42

          Sur quatre des explications des relations entre les tables, il n'y en a qu'une que je n'ai pas listé dans ma remarque, la seule est donc la troisième dans ton message.
          • Partager sur Facebook
          • Partager sur Twitter

          Face a quelqu'un pour qui l'on n'éprouve que de l'aversion et du mépris, les yeux d'un homme deviennent extrêmement froids et cruels.

            30 mars 2020 à 9:53:27

            Bonjour

            Je reviens vers vous car j'ai pas mal avancé.

            Finalement, j'ai préféré ne pas modifier les migrations.

            J'ai refait les entités qui génèrent des tables de jointures.

                    /**
                     * @ORM\ManyToMany(targetEntity="App\Entity\Teams", inversedBy="matchs_recevant")
                     * @ORM\JoinTable(
                     *  name="matchs_recevant",
                     *  joinColumns={
                     *      @ORM\JoinColumn(name="matchs_id", referencedColumnName="id")
                     *  },
                     *  inverseJoinColumns={
                     *      @ORM\JoinColumn(name="recevant_id", referencedColumnName="id")
                     *  }
                     * )
                     */
                    private $recevant;
            
                    /**
                     * @ORM\ManyToMany(targetEntity="App\Entity\Teams", inversedBy="matchs_visitor")
                     * @ORM\JoinTable(
                     *  name="matchs_visitor",
                     *  joinColumns={
                     *      @ORM\JoinColumn(name="matchs_id", referencedColumnName="id")
                     *  },
                     *  inverseJoinColumns={
                     *      @ORM\JoinColumn(name="visitor_id", referencedColumnName="id")
                     *  }
                     * )
                     */
                    private $visitor;
                        $matchsIndex = $this->getDoctrine()
                            ->getRepository(Matchs::class)
                            ->findAll();
                        return $this->render('frontend/index.html.twig', [
                            'matchs' => $matchsIndex
                          ]);
                  {% for data in matchs %}
                        {{ dump(data) }}
                        {{ data.recevant }}
                    {% endfor %}
            App\Entity\Matchs {#716 ▼
              -description: "à Paris"
              -score: "2 - 0"
              -score_detail: ""
              -typeScore: "V"
              -season: Proxies\__CG__\App\Entity\Seasons {#742 ▶}
              -sport: Proxies\__CG__\App\Entity\Sports {#749 ▶}
              -competition: Proxies\__CG__\App\Entity\Competitions {#759 ▶}
              -sexe: Proxies\__CG__\App\Entity\Sexes {#769 ▶}
              -recevant: Doctrine\ORM\PersistentCollection {#801 ▼
                -snapshot: array:1 [ …1]
                -owner: App\Entity\Matchs {#716}
                -association: array:19 [ …19]
                -em: Doctrine\ORM\EntityManager {#401 …11}
                -backRefFieldName: "matchs_recevant"
                -typeClass: Doctrine\ORM\Mapping\ClassMetadata {#767 …}
                -isDirty: false
                #collection: Doctrine\Common\Collections\ArrayCollection {#803 ▶}
                #initialized: true
              }
              -visitor: Doctrine\ORM\PersistentCollection {#804 ▶}
              -id: 1
              -uuid: Ramsey\Uuid\Rfc4122\UuidV4 {#715 ▶}
              -published: true
              #createdAt: DateTimeImmutable @1585501201 {#713 ▶}
              #updatedAt: null
            }

            Je voulais afficher recevant et cela me retourne l'erreur

            An exception has been thrown during the rendering of a template ("Catchable Fatal Error: Object of class Doctrine\ORM\PersistentCollection could not be converted to string").
            

            Je suppose qu'il faut faire un array.....?

            Encore merci de votre aide

            Bonne journée

            -
            Edité par cyphos 30 mars 2020 à 9:56:23

            • Partager sur Facebook
            • Partager sur Twitter
              30 mars 2020 à 10:10:32

              Salut !

              L'erreur te dit que c'est déjà un(e forme de) tableau, donc pas besoin de re-convertir.

              Par contre, je ne pense pas que tes relations doivent être des ManyToMany. Un match a une équipe qui joue à domicile et une qui joue comme visiteur (deux relations différentes), et ces équipes peuvent jouer plusieurs matches, donc ce sont des Many(Match)ToOne(Equipe) (et à l'inverse One(Equipe)ToMany(Match)). A moins que tu puisses avoir deux équipes (ou plus) à domicile et deux (ou plus) visiteurs par matches !?  :ange:

              -
              Edité par Ymox 30 mars 2020 à 10:12:51

              • Partager sur Facebook
              • Partager sur Twitter
                30 mars 2020 à 10:24:50

                Bonjour Ymox

                OK, tu as raison

                je vais refaire la commande make:entity


                • Partager sur Facebook
                • Partager sur Twitter
                  30 mars 2020 à 10:49:21

                  Attention : tout comme tu as deux propriétés dans Match, tu en auras deux aussi dans Equipe. Sans entité intermédiaire concrète, je ne pense pas que tu puisses mapper deux relations (matches joué à domicile et en tant que visiteurs) sur une seule propriété.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    30 mars 2020 à 11:51:19

                    Auriez-vous une solution?

                    • Partager sur Facebook
                    • Partager sur Twitter
                      30 mars 2020 à 12:27:24

                      Oui, je crois même d'ailleurs l'avoir expliquée : deux propriétés dans Match, une pour l'équipe à domicile et une pour l'équipe en visite. Similairement, dans l'entité Equipe, une propriété pour les matches à domicile et une autre pour les matches où ils étaient visiteurs…

                      • Partager sur Facebook
                      • Partager sur Twitter
                        30 mars 2020 à 18:09:31

                        oui désolé

                        j'ai recrée les entités

                        il me reste juste à savoir comment afficher les données dans les templates

                        {% for match in matchs %}
                        {{ match.score }}
                        //{{ match.recevant }}??
                          {% endfor %}
                        



                        Encore merci de votre aide

                        voici le dump

                        App\Entity\Matchs {#1062 ▼
                          -description: "à Paris"
                          -score: "2 - 0"
                          -score_detail: ""
                          -typeScore: "V"
                          -season: Proxies\__CG__\App\Entity\Seasons {#1003 ▶}
                          -sport: Proxies\__CG__\App\Entity\Sports {#1019 ▶}
                          -competition: Proxies\__CG__\App\Entity\Competitions {#994 ▶}
                          -sexe: Proxies\__CG__\App\Entity\Sexes {#1065 ▶}
                          -recevant: Proxies\__CG__\App\Entity\Teams {#1077 ▼
                            +__isInitialized__: false
                            -title: null
                            -logo: null
                            -matchs: null
                            -id: 4
                            -uuid: null
                            #createdAt: null
                            #updatedAt: null
                             …2
                          }
                          -visitor: Proxies\__CG__\App\Entity\Teams {#1076 ▶}
                          -id: 1
                          -uuid: Ramsey\Uuid\Rfc4122\UuidV4 {#1006 ▶}
                          -published: true
                          #createdAt: DateTimeImmutable @1585569443 {#1022 ▶}
                          #updatedAt: null
                        }



                        -
                        Edité par cyphos 30 mars 2020 à 18:16:40

                        • Partager sur Facebook
                        • Partager sur Twitter
                          30 mars 2020 à 18:57:33

                          Doctrine ne récupère pas automatiquement tout de suite toutes les données de toutes les entités liées à une autre, cependant y accéder permettra bien de récupérer les données (en arrière-plan, une requête sera lancée).

                          Comment accéderais-tu à l'équipe jouant les locaux pour un match ? Similairement, comment accéderais-tu à l'équipe jouant les invitées pour un match ? Déjà en PHP, après adapter pour Twig n'est pas trop difficile.

                          -
                          Edité par Ymox 30 mars 2020 à 18:58:08

                          • Partager sur Facebook
                          • Partager sur Twitter
                            31 mars 2020 à 10:11:20

                            Rebonjour

                            En créant des fixtures ou des formulaires.

                            Désolé, j'essaie de comprendre 

                            • Partager sur Facebook
                            • Partager sur Twitter
                              31 mars 2020 à 10:17:27

                              Ça ce n'est pas comment y accéder, mais comment les enregistrer/créer.

                              Tu as une instance d'un objet Match avec toutes les données dans ton code PHP. Comment fais-tu pour afficher les données (donc y accéder) des locaux et des invités ?

                              • Partager sur Facebook
                              • Partager sur Twitter
                                31 mars 2020 à 10:32:50

                                si je comprends bien, j'accède par un contrôleur

                                        /**
                                         * @Route("/home", name="index")
                                         */
                                        public function index()
                                        {
                                            $matchsIndex = $this->getDoctrine()
                                                ->getRepository(Matchs::class)
                                                ->findAll();
                                
                                
                                //            dump($matchsIndex);
                                            return $this->render('frontend/index.html.twig', [
                                                'matchs' => $matchsIndex
                                            ]);
                                        }



                                • Partager sur Facebook
                                • Partager sur Twitter
                                  31 mars 2020 à 10:38:32

                                  :D Décidément

                                  Disons que tu as une variable $match, instance d'un objet Match, dans un code PHP. Comment est-ce que tu fais pour mettre dans une autre variable $visiteur l'équipe qui était visiteur pour ce match ? Sans que tu aies à coder de requête supplémentaire où que ce soit.
                                  C'est important, c'est une question de structure de données. Si tu ne sais pas comment sont organisées tes données entre elles (donc les relations entre tes entités et ce que tu peux en faire), déjà je ne comprendrais pas comment tu as pu créer tes entités, et ensuite je ne sais pas comment tu vas les utiliser. Et si c'est vraiment là le problème, je dirais que tu es allé un peu vite en besogne en t'attelant à Symfony.

                                  J'ai dit "mettre dans une autre variable", mais du coup on peut aussi afficher. Bref, on accède aux données depuis $match qui est un objet Match, en programmation orienté objet on parle d'instance de (la classe) Match.

                                  -
                                  Edité par Ymox 31 mars 2020 à 10:39:26

                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                    31 mars 2020 à 12:06:54

                                    Ce serait plus simple si vous jetez un coup d'oeil à mon repository que je viens de publier sur github

                                    voici le lien

                                    https://github.com/cyphos1973/docker-reims

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      31 mars 2020 à 12:16:03

                                      Je n'arrive pas à expliquer, et ce n'est pas une histoire de code, mais une question de concept.

                                      Pour accéder au titre du recevant en PHP, tu ferais $match->getRecevant()->getTitle(). Et pour afficher dans Twig : {{ match.recevant.title }}, par exemple. Similairement pour l'équipe reçue.

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        31 mars 2020 à 12:25:31

                                        Souvent, j'ai du mal à comprendre des trucs abstraits. c'est difficile pour moi.

                                        Encore merci pour votre patience et votre code.

                                        Là, je comprends mieux le code que les explications lol

                                        bonne journée

                                        • Partager sur Facebook
                                        • Partager sur Twitter

                                        [Symfony 4] générer une table avec 2 relations MtM

                                        × 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