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

Doctrine2 PHP Discussion :

Relation ManyToMany et persist pour une modification


Sujet :

Doctrine2 PHP

  1. #1
    Candidat au Club
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Août 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2012
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Relation ManyToMany et persist pour une modification
    Bonsoir à tous,

    Pour mon premier post, je commence fort !
    Je n'arrive pas à faire prendre en compte une modification pour une relation ManyToMany entre deux entités (Brand et User), mais uniquement dans un sens.
    Explications:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <?php
    //Class User
    /**
      * @ORM\ManyToMany(targetEntity="Brand", inversedBy="users", cascade={"persist"})
      * @Assert\Valid()
      */    
      private $brands;
     
    // Class Brand
    /**
      * @ORM\ManyToMany(targetEntity="User", mappedBy="brands", cascade={"persist"})
      * @Assert\Valid()
      */
      private $users;
    J'ai un formulaire pour modifier un utilisateur, je peux lui attribuer 0 ou plusieurs marques (input type="box") et ça marche !
    J'ai un formulaire pour modifier une marque, je peux lui attribuer 0 ou plusieurs utilisateurs (input type="box") et ça ne marche pas !

    Les modifications sont bien prises en compte sauf que l'utilisateur n'est pas lié à la marque. Alors que l'inverse marche !!

    Voici mon handler lors du clique sur modifier dans la partie modification de la marque:

    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
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    <?php
    public function onSuccess(Brand $brand)
        {
            $this->em->persist($brand);
     
            if($brand->getId())
            {
                /* SUPRESSION DES LIEUX */
                $originalLocations = array();
                foreach($this -> em -> getRepository('WinItAdminBundle:BrandLocation') -> findByBrand($brand -> getId()) as $location)
                {
                    $originalLocations[] = $location;
                }
     
                foreach($originalLocations as $location)
                {
                    foreach($brand->getLocations() as $key => $toDel)
                    {
                        if($toDel->getId() == $location->getId())
                        {
                            unset($originalLocations[$key]);
                        }
                    }
                }
     
                foreach($originalLocations as $location){
                    $this->em->remove($location);
                }
                /* FIN SUPRESSION DES LIEUX */
            }
     
     
            foreach($brand->getLocations() as $location)
            {
                $location->setModified = new \DateTime('now');
                $brand->addLocation($location);
                $this->em->persist($location);
            }
     
            // JUSTE CE FOREACH NE MARCHE PAS, LE RESTE MARCHE
            foreach($brand->getUsers() as $user)
            {
                $brand->addUser($user);
                $this->em->persist($user);
            }
     
            $brand->setModified(new \DateTime('now'));
            $this->em->persist($brand);
            $this->em->flush();
        }
    La seule partie qui ne marche pas est la dernière boucle foreach() (qui est sur les utilisateurs à lier à la marque).

    J'ai fait des test sur cette boucle est l'on reçoit bien les marques cochées !
    Je pense que le problème vient de la configuration des entités mais j'ai tout essayé également.

    Si quelqu'un peut m'aider ... ça m'aiderait bien :-D

    Merci à tous,

    Gaëtan

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    C'est un comportement "normal" de Doctrine, il s'agit du concept de owning et inverse side:
    http://docs.doctrine-project.org/en/...ociations.html

    concrètement ça pourrait se résoudre comme cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    //.......
            foreach($brand->getUsers() as $user)
            {
                $user->addBrand($brand);//les modifications sont calculées en fonction de l'attribut brands de user mais pas sur l'attribut users de brand
     
                $brand->addUser($user);//je vois pas à quoi ça sert             
                $this->em->persist($user);//les users ne sont pas déjà persisté?
            }
    //......

  3. #3
    Candidat au Club
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Août 2012
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Calvados (Basse Normandie)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Août 2012
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci pour cette réponse
    Le comportement à changé car je suis maintenant confronté à une erreur de type Exception au niveau de MySQL:

    SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '1-18' for key 'PRIMARY'

    J'ai trouvé pas mal de posts de gens sur Google qui avaient le même problème mais la réponse ne marche jamais pour mon cas

    Je réclame votre aime si ce n'est pas trop demander

    Merci beaucoup


    EDIT:

    Je précise aussi que cette méthode est utilisé pour l'ajout ET pour la modification ! Je pense de plus en plus que lors de la modification, on essais de créer (dupliquer) un utilisateur pour une marque... est-ce ça ? Il n'existe pas une méthode 'intelligente' qui devine si l'objet est déjà existant ou pas, et donc qui le modifie, le supprime ou l'ajoute en fonction de l'état actuel de la BDD ? J'avais pensé à la méthode refresh() de l'entityManager ?!

Discussions similaires

  1. Réponses: 3
    Dernier message: 03/09/2009, 16h26
  2. Réponses: 3
    Dernier message: 26/06/2008, 10h57
  3. Réponses: 3
    Dernier message: 27/05/2008, 06h26
  4. Réponses: 2
    Dernier message: 23/05/2008, 16h05
  5. Débuté (Aide pour une modif de serveur)
    Par mimagyc dans le forum C++
    Réponses: 8
    Dernier message: 20/12/2006, 23h19

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