2016-07-11 57 views
4

Ich arbeite an einem Formular mit 2 Eingabefeldern und einem Absenden-Button. Das erste Feld ist ein einfaches Dropdown (Kategorie), das andere jedoch ist ein Tag-Eingabefeld (Tag), in dem Sie mehrere Tags gleichzeitig eingeben können. Beide Felder akzeptieren nur vordefinierte Eingabeoptionen.Symfony2 ManytoMany bidirektionale Beziehung - Wie persistent persistent

Die Kategorie Optionswerte sind in Javascript fest einprogrammiert:

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

Die Optionen für Tag abgerufen werden, aus der tag Tabelle in der Datenbank. Hier ist der Screenshot der Datenbanktabellen:

enter image description here

Die Kategorie und Tag Entitäten zugeordnet sind Lehre der ManyToMany bidirektionale Beziehung, mit der Kategorie der besitzende Seite zu sein.

Hinweis: Ich bin mit Symfony nicht formType das Formular zu erstellen, stattdessen habe ich verwendet Javascript dafür.

Das Javascript funktioniert gut und ich bekomme die Eingabedaten in meinem Controller. Problem ist, dass ich nie eine ManytoMany Beziehung manuell beibehalten habe. Habe die Dokumente gelesen, bin mir aber nicht sicher, ob ich etwas verpasst habe. Hier

ist die Tag-Einheit (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 Kategorie Einheit (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 die Steuerung (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(); 
} 

Die $form_data ist ein arra y mit der Eingabekategorie und hinzugefügten Tags Details. Es sieht so aus:

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

Noch es bleibt nicht bestehen. Die var_dump($category); zeigt das ausgewählte Kategorieobjekt mit der Kategorie id und categoryname an, aber die zugehörige Eigenschaft tags ist leer. Hier

ist der Screenshot der Ausgabe:

enter image description here

Irgendwelche Ideen?

Schnelle Frage auf der Seite: Muss ich beide Seiten der Beziehungsdefinition cascade={"persist"} hier hinzufügen?

EDIT: Hier habe ich $form_data hart-codiert anstelle der Eingabe von Daten wie ich oben getan habe.Die DefaultController.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:

enter image description here

Wie Sie die tags Eigenschaft der Kategorie Objekt zu sehen ist noch leer.

Hoffe, dass dies helfen wird, das Problem besser zu verstehen. Warten auf Antwort ...

Antwort

0

Wenn immer die entsprechende Tag Entität von

$tag = $em->getRepository('AppBundle:Tag')->findOneById($tagId); 

tun eine Reihe von Sammlungen Ist das nicht der Wert von $ markieren?

Also möglicherweise Folgendes tun?

$category->addTag($tag[0]);