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

Symfony PHP Discussion :

Formulaire avec relation ManyToMany


Sujet :

Symfony PHP

  1. #1
    Membre régulier Avatar de Caranille
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2013
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 117
    Points : 70
    Points
    70
    Par défaut Formulaire avec relation ManyToMany
    Bonjour,

    Je viens ici pour exposer mon problème pour avoir votre avis car certaines personnes me disent que ce n'est pas possible.

    donc voilà je suis en train de faire un formulaire pour que le joueur puisse choisit un monstre qui est lié à la ville où se trouve le joueur, j'ai donc fait ceci:

    TownController.php

    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
    /**
        * @Security("has_role('ROLE_USER_WITH_CHARACTER') or has_role('ROLE_USER_MODERATOR') or has_role('ROLE_USER_ADMINISTRATOR')")
        */
        public function dungeonAction(Request $request)
        {
            $town = $this->getUser()->getCharacter()->getTown();
     
            $form = $this->get('form.factory')->create(TownMonsterType::class, $town);
            if ($request->isMethod('POST'))
            {
                $form->handleRequest($request);
                if ($form->isValid())
                {
                    $em = $this->getDoctrine()->getManager();
                    $em->persist($character);
                    $em->flush();
                    return $this->redirectToRoute('car_caranille_town_dungeon');
                }
            }
            return $this->render('CARCaranilleBundle:Town:Dungeon.html.twig', array('form' => $form->createView()));
        }
    TownMonsterType.php

    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
    51
    52
    53
    <?php
    namespace CAR\CaranilleBundle\Form;
     
    use CAR\CaranilleBundle\Repository\MonsterRepository;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolver;
    use Symfony\Bridge\Doctrine\Form\Type\EntityType;
    use Symfony\Component\Form\Extension\Core\Type\HiddenType;
    use Symfony\Component\Form\Extension\Core\Type\TextType;
    use Symfony\Component\Form\Extension\Core\Type\SubmitType;
     
    class TownMonsterType extends AbstractType
    {
        /**
         * {@inheritdoc}
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $town = $builder->getData()->getID();
     
            $builder
            ->add('monster', EntityType::class, array(
            'class'        => 'CARCaranilleBundle:Monster',
            'label' => 'Monstre: ',
            'choice_label' => 'name',
            'multiple'     => false,
            'query_builder' => function(MonsterRepository $repository) use($town)
            {
                return $repository->getMonsterListBuilder($town);
            }))
            ->add('save', SubmitType::class);
        }
     
        /**
         * {@inheritdoc}
         */
        public function configureOptions(OptionsResolver $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'CAR\CaranilleBundle\Entity\Town'
            ));
        }
     
        /**
         * {@inheritdoc}
         */
        public function getBlockPrefix()
        {
            return 'car_caranillebundle_town';
        }
    }
    MonsterRepository.php

    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
    <?php
     
    namespace CAR\CaranilleBundle\Repository;
     
    /**
     * MonsterRepository
     *
     * This class was generated by the Doctrine ORM. Add your own custom
     * repository methods below.
     */
    class MonsterRepository extends \Doctrine\ORM\EntityRepository
    {
        public function getMonsterListBuilder($town)
        {
            return $this
            ->createQueryBuilder('c')
            ->where('c.town = :town')
            ->setParameter('town', $town);
        }
    }
    Pourtant dans l'entité Town il y a une liaison ManyToMany vers Monster de façon bidirectionnelle

    Town.php

    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
    <?php
    namespace CAR\CaranilleBundle\Entity;
     
    use Doctrine\ORM\Mapping as ORM;
     
    /**
     * Town
     *
     * @ORM\Table(name="caranille_town")
     * @ORM\Entity(repositoryClass="CAR\CaranilleBundle\Repository\TownRepository")
     */
     
    class Town
    {
        /**
         * @var int
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        protected $id;
     
        /**
        * @ORM\ManyToMany(targetEntity="CAR\CaranilleBundle\Entity\Monster", mappedBy="town"))
        */
        private $monster;
    ...
    Sauf que cela ne fonctionne pas car il me dit:

    [Semantical Error] line 0, col 59 near 'town = :town': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.
    De plus je penses que envoyer l'id de la ville dans un query_builder est un peu moche car si je me suis embêté à faire une relation town <= > monster c'est bien pour l'utiliser sans devoir faire de requête ^^

    Donc comment faire en sorte que le menu déroulant affiche bien les monstres lié à cette ville ?

    Cordialement,

  2. #2
    Membre expert
    Avatar de dukoid
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2012
    Messages
    2 100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2012
    Messages : 2 100
    Points : 3 004
    Points
    3 004
    Par défaut
    tu as testé ta requete du repository ()avec un ID connu dans le controleur ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ... getMonsterListBuilder(1)

  3. #3
    Membre régulier Avatar de Caranille
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2013
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 117
    Points : 70
    Points
    70
    Par défaut
    Bonsoir,

    Même en mettant 1 directement cela ne fonctionne pas... mais si je change la requête en mettant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    return $this
    		->createQueryBuilder('c')
    		->where('c.name = :name')
    		->setParameter('name', "plop");
    Cela fonctionne il arrive bien a me trouver le monstre qui se nomme plop mais dès qu"il s'agit de l'attribut town il bug

    J'ai l'impression que l'attribut town l'embête et pas qu'un peu...

    Je ne sais que faire...

    P.S: Je viens d'ajouter ma base de donnée en sql dans la pièce jointe
    Cordialement,
    Fichiers attachés Fichiers attachés
    • Type de fichier : sql c9.sql (19,2 Ko, 59 affichages)

  4. #4
    Membre régulier Avatar de Caranille
    Homme Profil pro
    Développeur Web
    Inscrit en
    Août 2013
    Messages
    117
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 117
    Points : 70
    Points
    70
    Par défaut
    Bonsoir,

    Après des heures de batailles cela fonctionne je suis reparti sur la logique que il fallait créer la relation dans le querybuilder avec innerjoin pour ensuite filter et avec ceci

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    	return $this
    		->createQueryBuilder('c')
    		->innerJoin('c.town', 'monstertown')
    		->where('monstertown.id = :id')
    		->setParameter('id', $town);
    Cela fonctionne enfin, si je change l'id de la ville d'un monstre ça marche plus

    Maintenant le problème est que lors de la validation du formulaire j'ai le droit à ça

    The property "monster" in class "Proxies\__CG__\CAR\CaranilleBundle\Entity\Town" can be defined with the methods "addMonster()", "removeMonster()" but the new value must be an array or an instance of \Traversable, "CAR\CaranilleBundle\Entity\Monster" given.

    Ce qui est normal vu que je ne créer pas d'objet $town ni $monster :p

    Je cherche juste à créer un objet $monsterBattle qui est une autre entité qui correspond au monstre que le joueur va combattre et qui persistera dans la bdd sauf que dans me formulaire j'envoi l'objet town, comment faire pour récupérer un autre objet :p

    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
    	$town = $this->getUser()->getCharacter()->getTown();
     
        	$form = $this->get('form.factory')->create(TownMonsterType::class, $town);
    		if ($request->isMethod('POST')) 
    		{
    			$form->handleRequest($request);
    			if ($form->isValid()) 
    			{
    				$em = $this->getDoctrine()->getManager();
    				$em->persist($character);
    				$em->flush();
    				return $this->redirectToRoute('car_caranille_town_dungeon');
    			}
        	}
        	return $this->render('CARCaranilleBundle:Town:Dungeon.html.twig', array('form' => $form->createView()));
    Cordialement,

Discussions similaires

  1. Problème formulaire avec bouton Radio
    Par SwatAgent dans le forum ASP
    Réponses: 1
    Dernier message: 23/10/2010, 16h35
  2. [AC-2007] formulaire avec relations N N
    Par primo dans le forum IHM
    Réponses: 7
    Dernier message: 11/01/2010, 18h24
  3. problème formulaire avec checkbox
    Par toinou62 dans le forum Langage
    Réponses: 1
    Dernier message: 30/09/2007, 14h07
  4. [HQL] Pb avec relation ManyToMany
    Par jc63 dans le forum Hibernate
    Réponses: 1
    Dernier message: 26/07/2007, 14h35
  5. [Spring MVC] Problème formulaire avec Collection
    Par arN34 dans le forum Spring Web
    Réponses: 1
    Dernier message: 16/09/2006, 13h17

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