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 :

Persistence des données problématique sur un formulaire et des données en OneToOne [2.x]


Sujet :

Symfony PHP

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut Persistence des données problématique sur un formulaire et des données en OneToOne
    Bonjour à tous !
    Je suis en train de réaliser un site en symfony et mon problème est le suivant:
    J'ai une entité User, et une entité Artisan.
    Un artisan est un User, et un User n'est pas obligatoirement un artisan.
    Je suis donc en onetoone unidirectionnel de Artisan vers User.

    En utilisant toutes les commandes automatiques de symfony 2, j'ai créé mes formulaires, et je commence donc à les modifier.
    Pour la partie "Création" d'un artisan, symfony me met un champ user, qui est rendu sous forme de liste déroulante, me permettant de choisir n'importe quel utilisateur lors de las création d'un compte (pas top).

    J'ai donc modifié le formulaire Artisan afin qu'il embarque le formulaire User.

    Jusque là, tout va bien, l'affichage est Ok.

    Par contre, le problème viens au moment de la validation: L'objet User ne semble pas instancié, et symfony m'envoie paitre comme un malpropre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Catchable Fatal Error: Argument 1 passed to Freelance\UserBundle\Entity\Artisan::setUser() must be an instance of Freelance\UserBundle\Entity\User, array given, called in D:\Profils\Olivier\Documents\NetBeansProjects\Freelance\vendor\symfony\src\Symfony\Component\Form\Util\PropertyPath.php on line 347 and defined in D:\Profils\Olivier\Documents\NetBeansProjects\Freelance\src\Freelance\UserBundle\Entity\Artisan.php line 126
    Savez-vous comment me sortir de cette situation ?
    Sachant que j'aimerais qu'un utilisateur puisse être créé soit "seul", en utilisateur standard, soir en tant qu'Artisan, avec une formulaire embarqué de l'utilisateur standard, plus des informations additionnelles de l'artisan ?

    Merci à vous de m'avoir lu !

  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,
    As tu configuré l'option data_class de ton formulaire user?
    http://symfony.com/doc/current/book/...rms-data-class

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Je n'ai pas utilisé cette option, vu que je passe déjà le paramètre dans le contrôleur.
    D'ailleurs, le voici ce contrôleur:
    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
     
        /**
         * Displays a form to create a new Artisan entity.
         *
         * @Route("/new", name="artisan_new")
         * @Template()
         */
        public function newAction() {
            $entity = new Artisan();
            $form = $this->createForm(new ArtisanType(), $entity);
     
            return array(
                'entity' => $entity,
                'form' => $form->createView()
            );
        }
     
        /**
         * Creates a new Artisan entity.
         *
         * @Route("/create", name="artisan_create")
         * @Method("post")
         * @Template("FreelanceUserBundle:Artisan:new.html.twig")
         */
        public function createAction() 
        {
            $entity = new Artisan();
            $request = $this->getRequest();        
            $form = $this->createForm(new ArtisanType(), $entity);       
            $form->bindRequest($request);   
     
            if ($form->isValid()) {            
                $em = $this->getDoctrine()->getEntityManager();
     
                $em->persist($entity);
     
                $em->flush();
     
                return $this->redirect($this->generateUrl('artisan_show', array('id' => $entity->getId())));
            }
     
            return array(
                'entity' => $entity,
                'form' => $form->createView()
            );
        }
    (A noter que lorsque j'édite un enregistrement du même genre, mélangant les 2 formulaires, cela fonctionne. Je pense que le user n'est pas créé, et qu'il y a donc une violation de contrainte avec la clé étrangère liée).

  4. #4
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    J'ai finalement testé l'ajout du getDefaultOptions dans la classe User comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public function getDefaultOptions(array $options)
        {
            return array(
            'data_class' => 'Freelance\UserBundle\Entity\User',
        );
        }
    Le message d'erreur est différent, mais cela semble aller plus loin tout de même:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    A new entity was found through the relationship 'Freelance\UserBundle\Entity\Artisan#user' that was not configured to cascade persist operations for entity: accc. Explicitly persist the new entity or configure cascading persist operations on the relationship. If you cannot find out which entity causes the problem implement 'Freelance\UserBundle\Entity\User#__toString()' to get a clue.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Bon allez, j'ai trouvé:
    La solution d'ajout du Data_class m'a aidé, il fallait ensuite persister l'objet user de facon implicite.

    Ma méthode createAction est devenue:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    if ($form->isValid()) {
                $em = $this->getDoctrine()->getEntityManager();
     
                $em->persist($entity);
                $em->persist($entity->getUser());
     
                $em->flush();
     
                return $this->redirect($this->generateUrl('artisan_show', array('id' => $entity->getId())));
            }
    Et (pour rappel), j'ai rajouté ceci dans la classe User, afin de spécifier d'ou viennent les données, là aussi de manière implicite.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public function getDefaultOptions(array $options)
        {
            return array(
            'data_class' => 'Freelance\UserBundle\Entity\User',
        );
        }
    Merci beaucoup pour le coup de main

  6. #6
    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
    il fallait ensuite persister l'objet user de facon implicite
    tu peux également configurer un persist en cascade
    http://docs.doctrine-project.org/pro...ade-operations

  7. #7
    Membre à l'essai
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2011
    Messages
    14
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Février 2011
    Messages : 14
    Points : 13
    Points
    13
    Par défaut
    Tu veut dire le signaler sur l'annotation de ma variable User, dans mon objet artisan ?

  8. #8
    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
    oui comme cela.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    class Artisan
    {
        //...
        /**
         *
         * @OneToOne(targetEntity="User", mappedBy="artisan", cascade={"persist", "remove"})
         */
        private $user;
        //...
    }
    http://docs.doctrine-project.org/pro....html#onetoone

    Ce qui ne veut pas dire que le persist implicite dans le controller est mauvais, c'est même plus rapide que de configurer par annotation.
    Even though automatic cascading is convenient it should be used with care. Do not blindly apply cascade=all to all associations as it will unnecessarily degrade the performance of your application

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 1
    Dernier message: 11/11/2014, 21h21
  2. Réponses: 3
    Dernier message: 08/09/2014, 17h01
  3. tri sur date en fonction de données issues d'un formulaire
    Par emulamateur dans le forum Requêtes et SQL.
    Réponses: 5
    Dernier message: 27/07/2011, 20h02
  4. insertion des données saisies sur un formulaire
    Par vanesa dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 18/08/2008, 17h28
  5. Réponses: 3
    Dernier message: 25/02/2008, 10h18

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