问题
I have an object "person" with several collections ("documents", "contacts", "etc"). I would like to save "person" and automatically the collection too. This is my controller:
$em = $this->getDoctrine()->getManager();
$persona = new Persona();
$formulario = $this->createForm(
PersonaType::class,
$persona,
array('action' => $this->generateUrl('persona_create'),
'method' => 'POST')
);
$formulario->handleRequest($request);
$em->persist($persona);
$em->flush();
When I dump "$persona", I have the collection and all the information that I need to save, but when I persist it, I lose all the information of the collection except from the "persona" atributtes.
This is one collection of the entity "persona"
/**
* @ORM\OneToMany(targetEntity="PersonaContacto", mappedBy="idPersona",cascade={"persist"},orphanRemoval=true)
*/
private $contactos;
public function getContactos() {
return $this->contactos;
}
public function addContacto(PersonaContacto $persona_contacto) {
$this->contactos->add($persona_contacto);
}
public function removeContacto(PersonaContacto $persona_contacto) {
$this->contactos->removeElement($persona_contacto);
}
And finally, this is the part of the form when I use the collection
->add('contactos', CollectionType::class, array(
// each entry in the array will be "document" field
'entry_type' => PersonaContactoType::class,
'prototype' => true,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
// these options are passed to each "idioma" type
'entry_options' => array('label' => false, 'attr' => array('class' => 'contacto-box')
),
))
This is the .js that adds and removes elements. As I said, this .js is used by several collection in the same form.
jQuery(document).ready(function () {
//var collectionCount = 0;
jQuery('.add-another-collection').click(function (e) {
e.preventDefault();
var collectionList = $(this).parent().parent().parent().parent();
// grab the prototype template
var newWidget = collectionList.attr('data-prototype');
// replace the "__name__" used in the id and name of the prototype
// with a number that's unique to your emails
// end name attribute looks like name="contact[emails][2]"
//newWidget = newWidget.replace(/__name__/g, collectionCount);
//collectionCount++;
// create a new list element and add it to the list
var newTr = jQuery('<tr></tr>').html(newWidget);
newTr.appendTo(collectionList);
});
// handle the removal, just for this example
$(document).on('click', '.remove-collection', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
return false;
});
})
I don´t understand why the cascade persist is not working .
回答1:
Follow the doctrine documentation, add a mappedBy prop in your Persona OneToMany annotation and add the ManyToOne in PersonaContacto (http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional)
Then in Persona (may be useless, try it):
public function addContacto(PersonaContacto $persona_contacto) {
$this->contactos->add($persona_contacto);
$persona_contacto->setPersona($this);
}
回答2:
Use mappedBy in owning side
/**
* @ORM\OneToMany(targetEntity="PersonaContacto", mappedBy="xxx", cascade={"persist"},orphanRemoval=true)
*/
Use inversedBy in inverse side
inversedBy="xxx"
More details Bidirectional Associations
来源:https://stackoverflow.com/questions/48086257/symfony3-how-to-persist-an-object-with-its-collections