PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Formulaire One-to-Many-to-One avec attributs avec Symfony 3 / Doctrine

Vous avez rencontré l'un des problèmes les plus difficiles avec les formulaires Symfony. Heureusement, il existe une bonne documentation. Permettez-moi de résumer les étapes importantes.

Vous avez raison :l'entité Person doit connaître sa relation avec PersonJob si vous souhaitez manipuler cette relation du point de vue d'une personne. Vous devez donc ajouter une propriété :

// src/AppBundle/Entity/Person.php
/**
 * @ORM\OneToMany(targetEntity="PersonJob", mappedBy="person")
 */
private $personJobs;

public function __construct()
{
    $this->personJobs = new \Doctrine\Common\Collections\ArrayCollection();
}

et ensuite vous aurez dans le type de formulaire

// src/AppBundle/Form/PersonType.php
$builder
    ->add('name')
    ->add('firstname')
    ->add('personJobs', CollectionType::class, array(
        'entry_type'   => PersonJobType::class,
        'allow_add' => true,
    )
;

Notez le type de personJobs champ. Puisqu'une personne peut avoir plusieurs PersonJobs, vous avez besoin d'un type de formulaire qui peut gérer les collections. C'est le but du CollectionType intégré (consultez sa documentation ! ). Vous avez également besoin du type de formulaire PersonJobType , de sorte que CollectionType sait construire les sous-formulaires :

class PersonJobType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('comment')
            ->add('datestart', DateTimeType::class)
            ->add('dateend', DateTimeType::class)
            ->add('job') // requires Job::__toString() to be defined!
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\PersonJob'
        ));
    }
}

À des fins de débogage, remplacez votre contrôleur par

 public function testAction()
 {
    $person = new Person();
    $form = $this->createForm(PersonType::class, $person);
    $form->add('submit', SubmitType::class);

    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {
        print '<pre>';
        var_dump($form->getData());
        die();
    }

    return $this->render('default/index.html.twig', [
        'form' => $form->createView(),
    ]);
}

Maintenant, allez-y et copiez et collez le code Twig et Javascript de Ajout et suppression d'éléments (vous devez apporter des modifications mineures telles que le remplacement de form.emails avec form.personJobs ).

Le formulaire

Le formulaire ressemblera à

Juste le formulaire Personne avec un "Ajouter un autre PersonJob" lien :

Ajouter un PersonJob :

Ajouter un PersonJob :

Les données reçues

Soumettez le formulaire et voyez la sortie de var_dump :

object(AppBundle\Entity\Person)#247 (5) {
  ["id":"AppBundle\Entity\Person":private]=>
  NULL
  ["name":"AppBundle\Entity\Person":private]=>
  string(12) "Charles Dude"
  ["firstName":"AppBundle\Entity\Person":private]=>
  string(7) "Charles"
  ["active":"AppBundle\Entity\Person":private]=>
  bool(true)
  ["personJobs":"AppBundle\Entity\Person":private]=>
  object(Doctrine\Common\Collections\ArrayCollection)#248 (1) {
    ["elements":"Doctrine\Common\Collections\ArrayCollection":private]=>
    array(2) {
      [0]=>
      object(AppBundle\Entity\PersonJob)#962 (6) {
        ["id":"AppBundle\Entity\PersonJob":private]=>
        NULL
        ["comment":"AppBundle\Entity\PersonJob":private]=>
        string(19) "Something important"
        ["datestart":"AppBundle\Entity\PersonJob":private]=> 
        object(DateTime)#1088 (3) { … }
        ["dateend": …] => …
        ["person":"AppBundle\Entity\PersonJob":private]=>
        NULL
        ["job":"AppBundle\Entity\PersonJob":private]=>
        object(AppBundle\Entity\Job)#1171 (2) {
          ["id":"AppBundle\Entity\Job":private]=>
          int(2)
          ["name":"AppBundle\Entity\Job":private]=>
          string(5) "Job 2"
        }
      }
      [1]=> …
  }
}

Il reste deux choses à faire :

  1. Définissez la person propriété du PersonJob imbriqué entités correctement à la nouvelle personne (mais pas encore persistante).

  2. Parlez à Doctrine du nouveau PersonJob entités en appelant $em->persist(…) sur eux.

Documents pertinents :