Partage
  • Partager sur Facebook
  • Partager sur Twitter

Persit en cascade sur manytomany coté non proprio.

Coté mappedBy

Sujet résolu
    11 avril 2018 à 16:28:32

    Bonjour,

    j'ai deux entités liées avec un ManyToMany bidirectionnel.

    "Structure" et "Personne". "Personne" étant propriétaire de la relation.

    j'ai un mutliselect qui fonctionne bien coté "Personne" dans mon formulaire qui persite bien les modif que je fait.

    Je met le même mutiselect pour pouvoir gérer la relation coté "Structure"... il affiche bien les valeurs liés à la création du formulaire.

    mais lorsque j'enregistre, il ne persiste rien de mes modifications concernant cette relation.

    class Structures
    {
    .....
    
     /**
         * 
         * @ORM\ManyToMany(targetEntity="App\Entity\Personnes", mappedBy="structure", cascade={"persist"})
         */
        private $personnes;
    
    .......
    
     /**
         * Add personne
         *
         * @param \App\Entity\Personnes $personne
         *
         * @return Structures
         */
        public function addPersonne(\App\Entity\Personnes $personne)
        {
            $this->personnes[] = $personne;
            
            // On lie la personne à la Structure
            $personne->addStructure($this);
            
    
            return $this;
        }
    }
    class Personnes
    {
    ........
    
    /**
         * @ORM\ManyToMany(targetEntity="App\Entity\Structures", inversedBy="personnes", cascade={"persist"})
         */
           
        private $structure;
        
    
    .........
    
    
        /**
         * Add structure
         *
         * @param \App\Entity\Structures $structure
         *
         * @return Personnes
         */
        public function addStructure(\App\Entity\Structures $structure)
        {
            $this->structure[] = $structure;
    
            return $this;
        }
    
    
    
    
    }

    A la fin du cours sur la bidirecitionalité j'ai l'impression d'avoir compris qu'il fallait faire un truc dans le " addPersonne " de "Structure" pour assurer la cohérence... mais je suis pas certains d'avoir bien compris.

    Une idée ?


    merci de votre aide

    -
    Edité par Chap291 11 avril 2018 à 17:38:10

    • Partager sur Facebook
    • Partager sur Twitter
      17 avril 2018 à 11:19:47

      Je me permet un petit up de mon post car je n'ai toujours pas réussi mon truc.

      Merci et bonne journée

      • Partager sur Facebook
      • Partager sur Twitter
        17 avril 2018 à 11:29:14

        Salut !

        Je n'ai que très rarement eu le souci de devoir spécifier deux propriétaires d'une ManyToMany, mais je me demande s'il ne suffirait pas de modifier Personnes::addStructure pour y appeler $structure->addPerson(). Afin d'éviter une boucle infinie, il faudrait auparavant tester si $structure est déjà contenue dans Personnes#structure ($this->structure->contains($structure), si je me souviens bien).

        Si je peux me permettre, j'espère que tu ne vas pas te mélanger les pinceaux entre collections et propriétés "simples". Le nom de tes classes est au pluriel, et le nom de ta collection de structures dans Personnes est au singulier…

        • Partager sur Facebook
        • Partager sur Twitter
          17 avril 2018 à 14:30:21

          Merci pour ton aide.

          En effet, j'ai mis des éléments au pluriel et d'autre aux singulier volontairement pour savoir ce que j'appelle.

          Mais ma logique est peut être un peu étrange, mais jusque là je m'en sortait... mais tu m'as mis le doute .. je vais re-regarder pourquoi j'ai appliqué cette logique.

          Concernant mon addStructure de Personnes; il était comme ça.

          public function addStructure(\App\Entity\Structures $structure)
              {
                  $this->structure[] = $structure;
                 
                  return $this;
              }

          J'ai bien tenté de mettre ce que tu m'as dis

           public function addStructure(\App\Entity\Structures $structure)
              {
                  //$this->structure[] = $structure;
                  $this->structure->contains($structure);
                  return $this;
              }

          Mais le résultat est le même.

          il ne stock pas les changements lorsque je passe par structure.

          Mais il le fait bien lorsque je passe par personne.

          En gros il faut voir ça comme une logique de groupe avec d'un coté les membre d'un groupe. et une personne est membre de X groupe.

          "Membre"  / "Membre de"

          En gros le problème serait du coté "Membre".

          Merci



          • Partager sur Facebook
          • Partager sur Twitter
            17 avril 2018 à 14:34:37

            Attention, quand j'ai parlé de $this->structure->contains($structure), c'était pour tester si la structure était bien dans la collection. Et si ce n'est pas le cas, il faut l'ajouter avec $structure->addPerson()

            • Partager sur Facebook
            • Partager sur Twitter
              17 avril 2018 à 15:28:56

              Du coup je suis pommé.

              tu aurais fais quoi dans le addPersonne de structure ? un truc comme ça ?

              public function addPersonne(\App\Entity\Personnes $personne)
                  {
                      $this->personnes[] = $personne;
                      
                      // On lie la personne à la Structure
                      if ($this->structure->contains($structure)){
                $personne->addStructure($this);

              } return $this; }

              Je t'avoue que je ne sais plus trop où j'en suis....

              Par contre cela fonctionne très bien de l'autre coté... je peux mettre des personne dans des groupes (structures)... mais depuis le goupe je ne peux pas ajouter de membres.

              -
              Edité par Chap291 17 avril 2018 à 15:38:23

              • Partager sur Facebook
              • Partager sur Twitter
                17 avril 2018 à 15:55:07

                J'ai très bien compris que ça ne fonctionnait que dans un sens pour l'instant. Répéter le problème ne va pas faire que la solution sera trouvée plus vite  :p

                Enlève la ligne 3.

                • Partager sur Facebook
                • Partager sur Twitter
                  17 avril 2018 à 17:16:46

                  LOL .. Désolé... 

                   public function addPersonne(\App\Entity\Personnes $personne)
                      {
                          //$this->personnes[] = $personne;
                          
                          // On lie la personne à la Structure
                          if ($personne->structure->contains($this)){
                              $this->addPersonne($personne);
                          
                          }
                          return $this;
                      }

                  Le problème reste le même si je commente la ligne 3.



                  • Partager sur Facebook
                  • Partager sur Twitter
                    17 avril 2018 à 17:46:09

                    Mouais, bon.

                    Il te faut soit ceci :

                    // Dans l'entité Structures
                    public function addPersonne(Personnes $personne)
                    {
                        $personne->addStructure($this);
                        $this->personnes[] = $personne;
                    }
                    // Dans l'entité Personnes
                    public function addStructure(Structures $structure)
                    {
                        if (!$this->structures->contains($structure)) {
                            $structure->addPersonne($this);
                        }
                    }

                    Soit ceci :

                    // Dans l'entité Structures
                    public function addPersonne(Personnes $personne)
                    {
                        if (!$this->personnes->contains($personne)) {
                            $personne->addStructure($this);
                        }
                    }
                    // Dans l'entité Personnes
                    public function addStructure(Structures $structure)
                    {
                        $structure->addPersonne($this);
                        $this->structures[] = $structure;
                    }

                    Mélanger les deux n'est pas une bonne idée, et ni l'une ni l'autre ne garantissent que tu puisses avoir deux propriétaires de la relation. Doctrine ne regarde les changements que du côté propriétaire (là où il y a inversedBy en cas de ManyToMany, cf. la documentation officielle)

                    Edit

                    Désolé, c'est pas demain la veille qu'on aura de quoi poster correctement…

                    Edit 2 par -L0Lock-

                    problème contourné...

                    -
                    Edité par Ymox 17 avril 2018 à 23:00:36

                    • Partager sur Facebook
                    • Partager sur Twitter
                      18 avril 2018 à 10:04:35

                      En effet, j'ai aussi constaté que lorsque l'on copie/colle du code sans le toucher -> la fenêtre de code est propre.

                      mais dès qu'on touche un petit truc -> c'est tout pété.

                      Concernant mon problème : Avec tes deux options c'est pareil. Il n'y a que le coté propriétaire qui stock

                      j'en conclue que c'est pas possible de faire ce que je veux faire avec doctrine.

                      C'est marrant, je pensais que c'était un besoin classique.

                      En tout cas merci de ta patience et de tes réponses.

                      Bonne journée

                      Edit :

                      En faite ... j'ai trouvé ici

                      il faut :

                      Mettre ça uniquement coté " mappedBy ". soit : ici sur l'entité structures

                          /**
                           * Add personne
                           *
                           * @param \App\Entity\Personnes $personne
                           *
                           * @return Structures
                           */
                          public function addPersonne(\App\Entity\Personnes $personne)
                          {
                             
                               if ( $this ->personnes->contains($personne)) {
                                  return ;
                              }
                              $this ->personnes[] = $personne;
                              $personne->addStructure( $this );
                       
                          }
                      
                          /**
                           * Remove personne
                           *
                           * @param \App\Entity\Personnes $personne
                           */
                          public function removePersonne(\App\Entity\Personnes $personne)
                          {
                            
                              $this ->personnes->removeElement($personne);
                              $personne->removeStructure( $this );
                          }

                      ensuite lorsque je contruit le formulaire il faut ajouter une propriété sur le champ de l'EntityType : "  'by_reference' => false,   "



                      Encore bonne journée

                      -
                      Edité par Chap291 18 avril 2018 à 14:08:38

                      • Partager sur Facebook
                      • Partager sur Twitter
                        18 avril 2018 à 14:44:39

                        Je revenais justement pour parler de by_reference, qui devrait compléter ma réponse précédente — il me semble qu'elle fait la même chose que ce que tu as pris chez KnpUniversity, mais écrit différemment.

                        • Partager sur Facebook
                        • Partager sur Twitter

                        Persit en cascade sur manytomany coté non proprio.

                        × 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