sql >> Database >  >> RDS >> PostgreSQL

Eén-op-veel-op-één met attributen Vorm met Symfony 3 / Doctrine

U bent een van de moeilijkste problemen tegengekomen met Symfony-formulieren. Gelukkig is er goede documentatie. Laat me de belangrijke stappen samenvatten.

Je hebt gelijk:de entiteit Persoon moet op de hoogte zijn van zijn relatie met PersonJob als je die relatie vanuit het oogpunt van een persoon wilt manipuleren. U moet dus een eigenschap toevoegen:

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

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

en dan heb je in het vormtype

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

Let op het type personJobs veld. Aangezien een persoon veel PersonJobs kan hebben, hebt u een formuliertype nodig dat verzamelingen aankan. Dit is het doel van het ingebouwde CollectionType (bekijk de documentatie! ). U hebt ook het formuliertype PersonJobType . nodig , zodat CollectionType weet hoe de subformulieren moeten worden gebouwd:

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

Wijzig voor foutopsporingsdoeleinden uw 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(),
    ]);
}

Ga je gang en kopieer en plak de Twig- en Javascript-code van Items toevoegen en verwijderen (je moet kleine wijzigingen aanbrengen, zoals het vervangen van form.emails met form.personJobs ).

Het formulier

Het formulier ziet eruit als

Alleen het Persoonsformulier met een 'Nog een PersonJob toevoegen' link:

Een PersonJob toevoegen:

Nog iets toevoegen PersonJob:

De ontvangen gegevens

Verzend het formulier en bekijk de uitvoer van 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]=> …
  }
}

Er moeten nog twee dingen worden gedaan:

  1. Stel de person in eigenschap van de geneste PersonJob entiteiten correct naar de nieuwe (maar nog niet bestaande) Persoon.

  2. Vertel Doctrine over de nieuwe PersonJob entiteiten door $em->persist(…) . aan te roepen op hen.

Relevante documentatie:




  1. Is er een verschil tussen deze twee vragen?

  2. Hoe twee kolommen SELECTEREN, waarbij één kolom DISTINCT moet zijn?

  3. Bouw dynamische WHERE-clausule in mySQL

  4. Hoe gegevens met nullen in welsprekendheid op te halen