Symfony2 ManytoMany bidirektionale Beziehung - So bleiben Sie manuell bestehen

Ich arbeite an einem Formular mit 2 Eingabefeldern und einer Senden-Schaltfläche. Das erste Feld ist ein einfaches Dropdown-Feld (Kategorie), das andere Feld ist ein Tags-Eingabefeld (Tag), in das Sie mehrere Tags gleichzeitig eingeben können. Beide Felder akzeptieren nur vordefinierte Eingabemöglichkeiten.

Die Werte der Kategorieoptionen sind in Javascript fest codiert:

categories = [
                        {"id": 1, "categoryname": "standard"},
                        {"id": 2, "categoryname": "premium"},
                        {"id": 3, "categoryname": "gold"}
                    ];

Die Optionen für das Tag werden aus dem @ abgerufetag Tabelle in der Datenbank. Hier ist der Screenshot der Datenbanktabellen:

Die Entitäten "Category" und "Tag" sind mit der bidirektionalen Beziehung "ManytoMany" von Doctrine verknüpft, wobei die Kategorie die besitzende Seite ist.

Hinwei: Ich verwende Symfony @ nicformType um das Formular zu erstellen, habe ich stattdessen Javascript verwendet.

Das Javascript funktioniert einwandfrei und ich erhalte die Eingabedaten in meinem Controller.Proble ist, dass ich nie eine ManytoMany-Beziehung manuell beibehalten habe. Ich habe die Dokumentation gelesen, bin mir aber nicht sicher, ob ich etwas verpasst habe.

Hier ist die Tag-Entität Tag.php):

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Category;

/**
 * Tag
 *
 * @ORM\Table(name="tag")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\TagRepository")
 */
class Tag {

    /**
     * @var int
     *
     * @ORM\Column(name="Id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * 
     * @var string
     *
     * @ORM\Column(name="TagName", type="string")
     */
    protected $tagname;

    /**
     * @ORM\ManyToMany(targetEntity="Category", mappedBy="tags")
     */
    protected $categories;

    /**
     * @return ArrayCollection 
     */
    public function __construct() {
        $this->categories = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId()
    {
        return $this->id;
    }


    /**
     * Set id
     *
     * @return Tag 
     */
    public function setId($id)
    {
        return $this->id = $id;
    }

    /**
     * Set tagname
     *
     * @param string $tagname
     * @return Tag
     */
    public function setTagname($tagname)
    {
        $this->tagname = $tagname;

        return $this;
    }

    /**
     * Get tagname
     *
     * @return string 
     */
    public function getTagname()
    {
        return $this->tagname;
    }

    /**
     * Add categories
     *
     * @param \AppBundle\Entity\Category $categories
     * @return Tag
     */
    public function addCategory(\AppBundle\Entity\Category $categories)
    {
        $this->categories[] = $categories;

        return $this;
    }

    /**
     * Remove categories
     *
     * @param \AppBundle\Entity\Category $categories
     */
    public function removeCategory(\AppBundle\Entity\Category $categories)
    {
        $this->categories->removeElement($categories);
    }

    /**
     * Get categories
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getCategories()
    {
        return $this->categories;
    }
}

Hier ist die Entität Category Category.php):

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use AppBundle\Entity\Tag;

/**
 * Category
 *
 * @ORM\Table(name="category")
 * @ORM\Entity(repositoryClass="AppBundle\Repository\CategoryRepository")
 */
class Category {

    /**
     * @var int
     *
     * @ORM\Column(name="Id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     * 
     * @var string
     *
     * @ORM\Column(name="CategoryName", type="string")
     */
    protected $categoryname;

    /**
     * 
     * @var string
     *
     * @ORM\Column(name="Description", type="string")
     */
    protected $description;

    /**
     * @ORM\ManyToMany(targetEntity="Tag", cascade={"persist"}, inversedBy="categories")
     */
    protected $tags;

    /**
     * @return ArrayCollection 
     */
    public function __construct() {
        $this->tags = new ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer 
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Set id
     *
     * @return Category 
     */
    public function setId($id) {
        return $this->id = $id;
    }

    /**
     * Set categoryname
     *
     * @param string $categoryname
     * @return Category
     */
    public function setCategoryname($categoryname) {
        $this->categoryname = $categoryname;

        return $this;
    }

    /**
     * Get categoryname
     *
     * @return string 
     */
    public function getCategoryname() {
        return $this->categoryname;
    }

    /**
     * Set description
     *
     * @param string $description
     * @return Category
     */
    public function setDescription($description) {
        $this->description = $description;

        return $this;
    }

    /**
     * Get description
     *
     * @return string 
     */
    public function getDescription() {
        return $this->description;
    }

    /**
     * Add tags
     *
     * @param \AppBundle\Entity\Tag $tags
     * @return Category
     */
    public function addTag(\AppBundle\Entity\Tag $tags) {
        $this->tags[] = $tags;

        return $this;
    }

    /**
     * Remove tags
     *
     * @param \AppBundle\Entity\Tag $tags
     */
    public function removeTag(\AppBundle\Entity\Tag $tags) {
        $this->tags->removeElement($tags);
    }

    /**
     * Get tags
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTags() {
        return $this->tags;
    }

}

Hier ist der Controller DefaultController.php):

/**
 * @Route("/formsubmit", options={"expose"=true}, name="my_route_to_submit")
 */
public function submitAction(Request $request) {
    $jsonString = file_get_contents('php://input');
    $form_data = json_decode($jsonString, true);

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

    // set category details
    $categoryId = $form_data[0]['id'];
    $category = $em->getRepository('AppBundle:Category')->findOneById($categoryId);

    // set tags
    $len = count($form_data[1]);

    for ($i = 0; $i < $len; $i++) {
        $tagId = $form_data[1][$i]['id'];
        $tag = $em->getRepository('AppBundle:Tag')->findOneById($tagId);
        $category->addTag($tag);
    }

    // persist/save in database
    $em->persist($category);
    $em->flush();
}

Das$form_data ist ein Array mit der Eingabekategorie und den hinzugefügten Tags. Es sieht aus wie das

$form_data = [
            ['id' => 3, 'categoryname' => 'gold'],
            [
                ['id' => 1, 'tagname' => 'wifi'],
                ['id' => 4, 'tagname' => 'geyser'],
                ['id' => 2, 'tagname' => 'cable']
            ]
        ];

Doch es bleibt nicht bestehen. Dasvar_dump($category); das ausgewählte Kategorieobjekt mit der Kategorie @ anzeigid undcategoryname, aber das zugehörigetags Eigenschaft ist leer.

Hier ist der Screenshot der Ausgabe:

Irgendwelche Ideen

Schnelle Frage auf der Seite: Muss ich @ hinzufügcascade={"persist"} zu beiden Seiten der Beziehungsdefinition hier?

BEARBEITEN Hier habe ich hart codiert$form_data anstatt Eingabedaten wie oben zu verwenden. DasDefaultController.php :

    /**
     * @Route("/formsubmit", options={"expose"=true}, name="my_route_to_submit")
     */
    public function submitAction(Request $request) {
        $form_data = [
            ['id' => 3, 'categoryname' => 'gold'],
            [
                ['id' => 1, 'tagname' => 'wifi'],
                ['id' => 4, 'tagname' => 'geyser'],
                ['id' => 2, 'tagname' => 'cable']
            ]
        ];

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

        // set category details
        $categoryId = $form_data[0]['id'];
        $category = $em->getRepository('AppBundle:Category')->findOneById($categoryId);

        // set tags
        $len = count($form_data[1]);

        for ($i = 0; $i < $len; $i++) {
            $tagId = $form_data[1][$i]['id'];
            $tag = $em->getRepository('AppBundle:Tag')->findOneById($tagId);
//            $tag->addCategory($category);
            $category->addTag($tag);
        }
        var_dump($category);
        exit;

        // persist/save in database
        $em->persist($category);
        $em->flush();
    }

Der Reglerausgang:

ie Sie das @ sehen könntags -Eigenschaft des Kategorieobjekts ist noch leer.

Hoffentlich hilft dies dabei, das Problem besser zu verstehen. Bitte um Antwort..

Antworten auf die Frage(2)

Ihre Antwort auf die Frage