PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Uno-a-molti-a-uno con attributi Forma con Symfony 3 / Doctrine

Ti sei imbattuto in uno dei problemi più difficili con i moduli Symfony. Fortunatamente, c'è una buona documentazione. Consentitemi di riassumere i passaggi importanti.

Hai ragione:l'entità Persona deve conoscere la sua relazione con PersonJob se vuoi manipolare quella relazione dal punto di vista di una Persona. Quindi devi aggiungere una proprietà:

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

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

e poi avrai nel tipo di modulo

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

Prendere nota del tipo di personJobs campo. Poiché una persona può avere molti PersonJob, è necessario un tipo di modulo in grado di gestire raccolte. Questo è lo scopo del CollectionType integrato (controlla la sua documentazione! ). È necessario anche il tipo di modulo PersonJobType , in modo che CollectionType sa come costruire i sotto-moduli:

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'
        ));
    }
}

Per scopi di debug, cambia il tuo controller in

 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(),
    ]);
}

Ora vai avanti e copia e incolla il codice Twig e Javascript da Aggiunta e rimozione di elementi (devi apportare piccole modifiche come la sostituzione di form.emails con form.personJobs ).

Il modulo

Il modulo sarà simile a

Solo il modulo Persona con un "Aggiungi un'altra personaJob" collegamento:

Aggiunta di un lavoro personale:

Aggiunta di un PersonJob:

I dati ricevuti

Invia il modulo e guarda l'output di 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]=> …
  }
}

Restano due cose da fare:

  1. Imposta la person proprietà del PersonJob annidato entità propriamente alla nuova (ma non ancora persistente) Persona.

  2. Parla a Doctrine del nuovo PersonJob entità chiamando $em->persist(…) su di loro.

Documentazione pertinente: