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:
-
Establecer la
person
propiedad delPersonJob
anidado entidades correctamente a la Persona nueva (pero aún no conservada). -
Cuéntale a Doctrine sobre el nuevo
PersonJob
entidades llamando a$em->persist(…)
en ellos.