Symfony3 - How to persist an object with its collections?

雨燕双飞 提交于 2020-01-11 13:00:44

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!