sql >> Base de Datos >  >> RDS >> PostgreSQL

One-to-Many-to-One con atributos Form con Symfony 3 / Doctrine

Te has encontrado con uno de los problemas más difíciles con los formularios de Symfony. Afortunadamente, hay buena documentación. Permítanme resumir los pasos importantes.

Tiene razón:la entidad Persona necesita conocer su relación con PersonJob si desea manipular esa relación desde el punto de vista de una Persona. Entonces necesita agregar una propiedad:

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

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

y luego tendrás en el tipo de formulario

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

Tenga en cuenta el tipo de personJobs campo. Dado que una persona puede tener muchos trabajos de persona, necesita un tipo de formulario que pueda manejar colecciones. Este es el propósito del CollectionType incorporado (consulte su documentación! ). También necesita el tipo de formulario PersonJobType , de modo que CollectionType sabe cómo construir los subformularios:

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

Para propósitos de depuración, cambie su controlador a

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

Ahora adelante, copie y pegue el código Twig y Javascript de Agregar y eliminar elementos (tiene que hacer cambios menores como reemplazar form.emails con form.personJobs ).

La forma

El formulario se verá como

Solo el formulario Persona con un “Agregar otro trabajo de persona” enlace:

Adición de un PersonJob:

Agregar algo PersonJob:

Los datos recibidos

Envíe el formulario y vea el resultado de 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]=> …
  }
}

Quedan dos cosas por hacer:

  1. Establecer la person propiedad del PersonJob anidado entidades correctamente a la Persona nueva (pero aún no conservada).

  2. Cuéntale a Doctrine sobre el nuevo PersonJob entidades llamando a $em->persist(…) en ellos.

Documentación relevante: