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

En-til-mange-til-en med attributter Form med Symfony 3 / Doktrin

Du er stødt på et af de sværeste problemer med Symfony-formularer. Heldigvis er der noget god dokumentation. Lad mig opsummere de vigtige trin.

Du har ret:Entitetspersonen skal vide om sit forhold til PersonJob, hvis du vil manipulere dette forhold fra en persons synspunkt. Så du skal tilføje en ejendom:

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

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

og så vil du have i formulartypen

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

Bemærk typen af ​​personJobs Mark. Da en person kan have mange PersonJobs, skal du bruge en formulartype, der kan håndtere samlinger. Dette er formålet med den indbyggede CollectionType (tjek dokumentationen! ). Du skal også bruge formulartypen PersonJobType , så CollectionType ved, hvordan man bygger underformularerne:

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

Til fejlfindingsformål skal du ændre din controller til

 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 videre og kopier og indsæt Twig og Javascript-koden fra Tilføjelse og fjernelse af elementer (du skal foretage mindre ændringer, såsom at erstatte form.emails med form.personJobs ).

Formularen

Formularen vil se sådan ud

Kun personformularen med "Tilføj endnu et personjob" link:

Tilføjelse af et personjob:

Tilføjelse af endnu et PersonJob:

De modtagne data

Indsend formularen og se output fra 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]=> …
  }
}

To ting mangler at blive gjort:

  1. Indstil person egenskaben for den indlejrede PersonJob enheder korrekt til den nye (men endnu ikke beståede) person.

  2. Fortæl Doctrine om det nye PersonJob enheder ved at kalde $em->persist(…) på dem.

Relevant dokumentation:




  1. Hvordan finder man nth rank i MySQL?

  2. Hvad skal du kigge efter, hvis din MySQL-replikering halter

  3. Sådan tjekker du din MySQL-version

  4. Python DPI-1047 Kan ikke finde dlopen(libclntsh.dylib) på macOS