PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

One-to-Many-to-One mit Attributen Formular mit Symfony 3 / Doctrine

Sie sind auf eines der schwierigsten Probleme mit Symfony-Formularen gestoßen. Glücklicherweise gibt es eine gute Dokumentation. Lassen Sie mich die wichtigsten Schritte zusammenfassen.

Sie haben Recht:Die Entität Person muss über ihre Beziehung zu PersonJob Bescheid wissen, wenn Sie diese Beziehung aus der Sicht einer Person manipulieren möchten. Sie müssen also eine Eigenschaft hinzufügen:

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

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

und dann haben Sie im Formulartyp

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

Beachten Sie den Typ des personJobs aufstellen. Da eine Person viele PersonJobs haben kann, benötigen Sie einen Formulartyp, der Sammlungen verarbeiten kann. Dies ist der Zweck des eingebauten CollectionType (Sehen Sie sich seine Dokumentation an! ). Außerdem benötigen Sie den Formulartyp PersonJobType , sodass CollectionType weiß, wie man die Unterformulare baut:

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

Ändern Sie zu Debugging-Zwecken Ihren Controller auf

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

Machen Sie jetzt weiter und kopieren und fügen Sie den Twig- und Javascript-Code von Elemente hinzufügen und entfernen (Sie müssen kleinere Änderungen vornehmen, z. B. das Ersetzen von form.emails mit form.personJobs ).

Das Formular

Das Formular sieht folgendermaßen aus:

Nur das Personenformular mit einem „Weiteren Personenjob hinzufügen“ Link:

PersonJob hinzufügen:

Einen weiteren PersonJob hinzufügen:

Die empfangenen Daten

Senden Sie das Formular ab und sehen Sie sich die Ausgabe von var_dump an :

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]=> …
  }
}

Zwei Dinge müssen noch getan werden:

  1. Legen Sie die person fest -Eigenschaft des verschachtelten PersonJob Entitäten ordnungsgemäß an die neue (aber noch nicht beibehaltene) Person.

  2. Informieren Sie Doctrine über den neuen PersonJob Entitäten durch Aufruf von $em->persist(…) auf ihnen.

Relevante Dokumentation: