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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre émérite 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
    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 confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    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
    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.

  3. #3
    Membre émérite 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
    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 éprouvé

    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
    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 émérite 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
    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 émérite 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
    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...

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