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 :

Formulaires encapsulés et sauvegarde des objets


Sujet :

Symfony PHP

  1. #1
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut Formulaires encapsulés et sauvegarde des objets
    Nouvelle énigme : j'ai un formulaire à encapsuler dans un autre pour gérer la création de deux objets liés.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    class FooForm extends BaseFooForm {
        public function configure() {
    	$embeddedForm = new EmbeddedForm(new Embedded());
    	$this->embedForm('embed', $embeddedForm);
        }
    }
    J'avais cru comprendre qu'en pareil cas (1), la sauvegarde des objets se faisait en cascade. Ce n'est pas le cas et la sauvegarde plante sur des problèmes de contraintes : l'objet Embedded pointé par l'objet Foo devrait être inséré en base avant Foo, comme il en l'est pas, la requête INSERT de l'objet Foo échoue.

    Que dois-je faire pour obtenir cela ?


    (1) http://www.symfony-project.org/more-...sic_form_setup

  2. #2
    Expert éminent
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Points : 8 486
    Points
    8 486
    Par défaut
    C'est ce que j'avais compris aussi.

    En principe on part d'une table A vers B avec une relation 1-n. Donc on devrait avoir dans B un champ du genre "a_id".

    Et je ne vois pas où la contrainte référentiel peut intervenir.

    A-tu essayé de construire l'exemple donné dans la doc ?

    C'est un de mes projets de tester ça mais j'ai un projet qui commence un peu à chauffer et il ne va pas être facile de tester la chose.
    Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).

    • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
    • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
    • Une discussion est terminée ? Alors le bouton est votre ami !

  3. #3
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Je vais reprendre l'exemple du tutoriel pour essayer de voir d'où vient le problème.

    Dans mon cas, c'est en fait une relation n-n : une Actualité référence plusieurs Livres, avec une table d'association ActualiteLivre : id_actu, id_livre, commentaires.

    Côté backend, toujours créé via doctrine:generate-admin, j'ai ajouté une object_action dans la liste des Actus : ajouter un livre. Cliquer sur le lien renvoie vers la page de création d'un objet ActualiteLivre initialisé avec l'Actualité de départ.

    Là où j'ai déjà du rater quelque chose, c'est que sur le formulaire de création de cet objet, les champs id_actu et id_livre sont hidden, et pas initialisés. Je soupçonne que j'ai oublié un paramétrage quelque part et que tout vient de là...

  4. #4
    Membre actif

    Homme Profil pro
    Software Engineer
    Inscrit en
    Août 2004
    Messages
    173
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Software Engineer
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Août 2004
    Messages : 173
    Points : 220
    Points
    220
    Par défaut
    Bonjour,

    La documentation n'a jamais été très claire sur le sujet des embedForms (et depuis la 1.3, les embedRelations).

    Voici personnellement la technique que j'emploie pour créer ce genre de formulaire (pour une relation 1-n classique) :

    Supposons un formulaire A qui contient B.

    nous aurons dans la classe AForm
    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
     
    public function configure()
    {
       $this->useFields(array(
         'B_id';
       ));
     
       $this->widgetSchema['B_id'] = new sfWidgetFormInputHidden();
     
       if($this->isNew())
       {
         $b = new B();
         $this->getObject()->setB($b);  
       }
       else
       {
          $b = $this->getObject()->getB();
       }
     
       $this->embedForm('B', new BForm($b));
    }
    Le champ hidden conserve la relation avec B, et permet de déclencher (ou l'insert) de B lors du $form->save();

    Si le formulaire BForm n'est destiné qu'à être encapsulé, le mieux est alors de faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    unset($this['B_id']);
    dans la classe BForm

  5. #5
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    OK, merci pour le tuyau, j'essayerai ça... si j'arrive à ce stade.
    Là tout de suite, j'avoue que je commence à désespérer. Car pour rester sur ma lancée, j'ai commencé à préparer l'embed comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class ActualiteForm extends BaseActualiteForm {
        public function configure() {
    	unset($this['created_at'], $this['updated_at']);
     
    	// Insertion du formulaire pour l'ajout d'un livre
    	$actuLivre = new ActualiteLivre();
    	$actuLivre->setActualite($this->getObject());
    //	$form = new ActualiteLivreForm();
    // ...
        }
    }
    A ce stade, aucun formulaire n'est encore ajouté.
    Si je vais en edit sur une Actualité et que je sauvegarde, tout va bien.
    Maintenent, je décommente la première ligne de commentaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class ActualiteForm extends BaseActualiteForm {
        public function configure() {
    	unset($this['created_at'], $this['updated_at']);
     
    	// Insertion du formulaire pour l'ajout d'un livre
    	$actuLivre = new ActualiteLivre();
    	$actuLivre->setActualite($this->getObject());
    	$form = new ActualiteLivreForm();
    // ...
        }
    }
    Je retourne en edit sur une Actualité, je sauvegarde et patatras, tout plante.
    Cause : mon formulaire ActualiteForm a désormais comme tag HTML le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    <form method="post" action="/backend_dev.php/actualite/No+description+for+object+of+class+%22ActualiteLivre%22">
    Le message No+description+for+object+of+class+%22ActualiteLivre%22" vient du fait que le __toString() de ActualiteForm plante. Si je le surcharge, j'aurais le résultat surchargé dans le champ action du formulaire.

    Conclusion : le formulaire Actualite utilise pour son action les données d'ActualiteLivre.

    WTF ?

  6. #6
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    Bon, là encore j'ai fini par trouver un moyen de contourner le problème mais ce n'est pas très satisfaisant, même si ça marche.

    Dans le schema.yml, j'avais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ActualiteLivre:
      actAs: { Timestampable: ~ }
      columns:
        actualite_id: { type: integer(4), primary: true }
    [etc...]
      relations:
        Actualite:
          alias:        Actualite
          foreignType:  many
          foreignAlias: ActualiteLivre
          onDelete:     cascade
    En retirant la déclaration primary: true, le problème disparait....

    Reste que si j'ai besoin d'une clé multiple sur cette table, ne je saurais pas comment faire. Mais ça, ce sera pour une autre fois...

  7. #7
    Membre éprouvé Avatar de Herode
    Homme Profil pro
    Développeur Web
    Inscrit en
    Mars 2005
    Messages
    825
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2005
    Messages : 825
    Points : 933
    Points
    933
    Par défaut
    J'ai essayé la manipulation suggérée par Vivian. Dans mon cas :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
        public function configure() {
    	$this->useFields(array('date_actualite', 'actif', 'titre', 'texte', 'actulivre_id'));
    	$this->widgetSchema['actulivre_id'] = new sfWidgetFormInputHidden();
    etc..
    si j'ai bien suivi...
    'actulivre_id' est donc un champ 'bidon' ne figurant pas dans la base, ni dans schema.yml.
    Résultat, quand j'appelle la page d'edit sur un des objets concernés :
    Widget schema does not include the following field(s): actulivre_id

Discussions similaires

  1. Sauvegarder des objets
    Par romanzo dans le forum OpenCV
    Réponses: 11
    Dernier message: 15/12/2011, 16h12
  2. Problème pour sauvegarder des objets.
    Par Invité(e) dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/07/2009, 16h52
  3. [MySQL] formulaire html avec sauvegarde des données
    Par orke22 dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 23/04/2008, 19h55
  4. hibernate: sauvegarde des objet
    Par gibson700 dans le forum Hibernate
    Réponses: 2
    Dernier message: 07/08/2007, 17h32
  5. Sauvegarder des objets en XML
    Par flow++ dans le forum C++Builder
    Réponses: 1
    Dernier message: 17/08/2006, 17h19

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