lundi 13 avril 2015

Symfony: Persisting embedded forms and avoiding duplicate entries

I have been playing around with Symfony for about a month now. I like the framework so far, but I have run into a problem which is making me suspicious of the Form component.


Overview I have two forms, one each for the following entities:



  • Posts

  • Tags


They have a many to many bi-directional relationship. The Tags form is embedded in the Posts form to allow new tags to be created and associated with the post on the fly.


Problem This works just fine with cascade enabled when a new tag entry is used. However, if an existing tag entry is re-used, a unique constraint violation is triggered by the Tags entity. The embedded form basically works as a utility to only create new tags, where as I want to use it in a conditional scenario where existing tags are not inserted but only associated with the parent form.


In a bid to try and avoid duplication issues, I turned off cascade and played around with doctrine listeners. However, I couldn't find a way around it. Does any one have any ideas? I could obviously handle the form submission manually, but that would half-defeat the purpose of using the Form component.


Form Type



  • Both forms extend "AbstractType"


Controller




  • The particular action that handles the code looks something like this



    $em = $this->getDoctrine()->getManager();

    $entity = $em->getRepository('B4PGround0Bundle:Blog\\Blog')->find($id);

    if (!$entity) {
    throw $this->createNotFoundException('Unable to find Blog entity.');
    }

    $deleteForm = $this->createDeleteForm($id);
    $editForm = $this->createEditForm($entity);
    $editForm->handleRequest($request);

    if ($editForm->isValid()) {
    $em->flush();



Entities




  • Excerpt from the Blog class (Blog is the same as the aforementioned Posts)



    /**
    * @ORM\ManyToMany(targetEntity="Tag", inversedBy="blogs")
    * @ORM\JoinTable(name="tags_blogs")
    * @Assert\Valid()
    **/
    private $tags;
    .......
    public function addTag($tag)
    {
    $tags->addBlog($this);
    $this->tags[] = $tags;
    return $this
    }



  • Excerpt from the Tags class



    /**
    * @ORM\ManyToMany(targetEntity="Blog", mappedBy="tags")
    **/
    private $blogs;
    ....
    public function addBlog($blog)
    {
    $this->blogs[] = $blogs;
    return $this;
    }


    `




Aucun commentaire:

Enregistrer un commentaire