sql >> Databasteknik >  >> RDS >> PostgreSQL

En-till-många-till-en med attribut Form med Symfony 3 / Doktrin

Du har stött på ett av de svåraste problemen med Symfony-formulär. Lyckligtvis finns det bra dokumentation. Låt mig sammanfatta de viktiga stegen.

Du har rätt:Entitetspersonen behöver veta om sin relation med PersonJob om du vill manipulera den relationen från en persons synvinkel. Så du måste lägga till en egenskap:

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

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

och sedan kommer du att ha i formulärtypen

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

Notera typen av personJobs fält. Eftersom en person kan ha många PersonJobs behöver du en formulärtyp som kan hantera insamlingar. Detta är syftet med den inbyggda CollectionType (kolla in dokumentationen! ). Du behöver också formulärtypen PersonJobType , så att CollectionType vet hur man bygger underformulären:

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

För felsökningsändamål, ändra din kontroller till

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

Gå nu vidare och kopiera och klistra in Twig och Javascript-koden från Lägga till och ta bort objekt (du måste göra mindre ändringar som att ersätta form.emails med form.personJobs ).

Formuläret

Formuläret kommer att se ut

Bara personformuläret med "Lägg till ytterligare ett personjobb" länk:

Lägga till ett PersonJob:

Lägger till något PersonJob:

Datan som tas emot

Skicka formuläret och se utdata från 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]=> …
  }
}

Två saker återstår att göra:

  1. Ställ in person egenskapen för den kapslade PersonJob enheter korrekt till den nya (men ännu inte bevarade) personen.

  2. Berätta för Doctrine om det nya PersonJob enheter genom att anropa $em->persist(…) på dem.

Relevant dokumentation:




  1. Hämta TOP 10 rader utan att använda TOP eller LIMIT? – Veckans intervjufråga #247

  2. Spring Docker-container kan inte komma åt Postgres Docker-container

  3. Lägga till en raderingsknapp i PHP på varje rad i en MySQL-tabell

  4. Hämta BLOB från databasen, hur man sätter tillbaka dem