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

  1. #1
    Nouveau Candidat au Club
    Suppression de données entity relation ManyToMany
    Bonjour à tous,

    Je suis débutant sur Symfony et après avoir suivi quelques tutoriaux, je travaille sur un projet afin de me perfectionner!

    Il s'agit d'un gestionnaire d'évènements avec inscriptions des participants avec un back-office. En tant que visiteur, je peux m'inscrire à un ou plusieurs évènements via une select list d'un formulaire bootstrap.
    Une fois inscrit, l'administrateur peut accéder à son back-office et voir qui s'est inscrit dans tel ou tel évènement en sélectionnant un évènement précis et d'y consulter la liste.

    Mon problème, qui me semble pourtant très bête, est que si l'administrateur décide de supprimer un participant d'un évènement, le participant est supprimé dans la base de donnée et donc de tous les évènements auxquels celui-ci s'est inscrit. Alors que j'aimerais qu'il ne soit supprimé que de l'évènement en question.

    Pour moi, je pense que je dois créer une requête dans le fichier repository de mon évènement...

    Voici quelques parties du code que je pense être utile.

    Mon Entity Participant.php qui possède donc une relation ManyToMany :
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
        /**
         * @ORM\ManyToMany(targetEntity="App\Entity\Atelier", inversedBy="participants")
         */
        private $workshops;


    Et mon Entity Atelier.php :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
        /**
         * @ORM\ManyToMany(targetEntity="App\Entity\Participant", mappedBy="workshops")
         */
        private $participants;


    Et dans l'un de mes Controller, voici la fonction qui supprime le participant de tous les évènements donc :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        /**
         * @Route("/admin/delete_participant/{id}", name="delete_participant")
         */
        public function deleteParticipant(EntityManagerInterface $manager, Participant $participant) {
     
            $manager->remove($participant);
            $manager->flush();
     
            $this->addFlash('danger', "Le participant a bien été supprimé");
     
            return $this->redirectToRoute("admin_page", [
                'participant' => $participant,
            ]);
        }


    C'est vraiment au niveau de la requête que je dois créer où je bloque...

    Pourriez-vous me donner un petit coup de main s'il vous plaît ?

    Merci d'avance!

  2. #2
    Modérateur

    Si c'est du manytomany il manque les @ORMJoinTable

  3. #3
    Nouveau Candidat au Club
    Bonjour MaitrePylos,

    J'avais un peu lu concernant les @ORMJoinTable mais donc d'après toi, c'est bien vers cela que je dois aller...
    Je ne connais pas du tout comment ça fonctionne mais je vais creuser!

  4. #4
    Modérateur

    Oui car Sf, n'est pas la base de données et ne sait pas ce qu'il faut faire.?

  5. #5
    Nouveau Candidat au Club
    Apparemment je devrais remplacer

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /**
         * @ORM\ManyToMany(targetEntity="App\Entity\Atelier", inversedBy="participants")
         */
        private $workshops;


    par quelque chose comme ceci

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    * @ORM\JoinTable(name="participant_atelier",
         *         joinColumns = {@ORM\JoinColumn(name="participant_id", referencedColumnName="id", onDelete="CASCADE")},
         *         inverseJoinColumns={@ORM\JoinColumn(name="atelier_id", referencedColumnName="id")}
         *      )
    private $workshops;


    Donc en gros, je devrais utiliser le JoinTable sur la table participant_atelier qui contient les relation entre les id uniquement...

  6. #6
    Modérateur

    en fait il faut les deux :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
         /**
         * @ORM\ManyToMany(targetEntity="App\Entity\Atelier", inversedBy="participants")
         *  @ORM\JoinTable(name="participant_atelier",
         *         joinColumns = {@ORM\JoinColumn(name="participant_id", referencedColumnName="id", onDelete="CASCADE")},
         *         inverseJoinColumns={@ORM\JoinColumn(name="atelier_id", referencedColumnName="id")}
         *      )
         */
    private $workshops;

  7. #7
    Nouveau Candidat au Club
    Juste, je l'ai supprimé par erreur!

    Par contre, une fois cela fait, je ne vois pas trop comment remplacer ma fonction actuelle je t'avoue...

    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
     
    /**
         * @Route("/admin/{name}/delete_participant/{id}", name="delete_participant")
         */
        public function deleteParticipant(EntityManagerInterface $manager, Atelier $atelier, Participant $participant) {
     
            $atelier->removeParticipant($participant);
            $manager->flush();
     
            $this->addFlash('danger', "Le participant a bien été supprimé");
     
            return $this->redirectToRoute("admin_page", [
                'participant' => $participant,
            ]);
        }


    En imaginant que j'ai le nom de l'évènement dorénavant dans l'url et l'id du participant à supprimer, si je fais cela j'ai cette erreur qui apparaît

    App\Entity\Atelier object not found by the @ParamConverter annotation

  8. #8

  9. #9
    Nouveau Candidat au Club
    {name} appartient à l'Entity Atelier, cela me donne simplement le nom de l'atelier dans mon url

  10. #10
    Membre éprouvé
    bonjour,

    ManyToMany te généré une table associative (atelier_participant) en BD. Cette table de jointure n'est pas directement manipulable par une entité sous-jacente côté PHP pour pouvoir supprimer un participant d'un événement donné.
    Il faut enlever la relation ManyToMany dans les 2 entités(Participant et Atelier) et créer une entité intermédiaire(Inscription par exemple) qui va faire la liaison entre Atelier et Participant. Cette entité intermédiaire va configurer une relation ManyToOne vers Atelier et ManyToOne vers Participant. On obtient alors une association mono-directionnelle mais il est aussi possible de configurer une association bi-directionnelle du genre Atelier(OneToMany)--->Inscription(ManyToOne et/ou ManyToOne)--->Participant(OneToMany) à toi de voir ce qui te convient.

    Dans le cas d'une association mono-directionnelle, l'entité Inscription suivante configure seule les relations sur Atelier et Participant tandis que Atelier et Participant n'auront à configurer aucune relation. Pour afficher les événements auxquels sont inscrits les participants il faut effectuer une requête DQL ou QB depuis le repositoy de Inscription normal Inscription seule a connaissance des entités qui lui sont associées.
    Pour supprimer un participant d'un événement il suffit de supprimer l'id d'inscription.
    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
     
    //Inscription.php
     
        /**
         * @var int
         *
         * @ORM\Id
         * @ORM\GeneratedValue
         * @ORM\Column(type="integer")
         */
        private $id;
     
        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\Atelier")
         */
        private $atelier;
     
        /**
         * @ORM\ManyToOne(targetEntity="App\Entity\Participant")
         */
        private $participant;