php – Symfony2 ManytoMany双向关系 – 如何手动持久化
我正在处理一个包含2个输入字段和一个提交按钮的表单.第一个字段是简单的下拉列表(类别),但另一个字段是标签输入字段(标签),您可以一次输入多个标签.两个字段仅接受预定义的输入选项.
类别选项值在javascript中是硬编码的: categories = [ {"id": 1,"categoryname": "standard"},{"id": 2,"categoryname": "premium"},{"id": 3,"categoryname": "gold"} ]; 标记的选项是从数据库中的标记表中获取的.以下是数据库表的屏幕截图: Category和Tag实体与Doctrine的ManytoMany双向关系相关联,类别是拥有方. 注意:我没有使用Symfony formType来创建表单,而是我使用了javascript. javascript工作正常,我在控制器中获取输入数据.问题是我从未手动持有ManytoMany关系. 这是Tag实体(Tag.php): <?php namespace AppBundleEntity; use DoctrineCommonCollectionsArrayCollection; use DoctrineORMMapping as ORM; use AppBundleEntityCategory; /** * Tag * * @ORMTable(name="tag") * @ORMEntity(repositoryClass="AppBundleRepositoryTagRepository") */ class Tag { /** * @var int * * @ORMColumn(name="Id",type="integer") * @ORMId * @ORMGeneratedValue(strategy="AUTO") */ protected $id; /** * * @var string * * @ORMColumn(name="TagName",type="string") */ protected $tagname; /** * @ORMManyToMany(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 AppBundleEntityCategory $categories * @return Tag */ public function addCategory(AppBundleEntityCategory $categories) { $this->categories[] = $categories; return $this; } /** * Remove categories * * @param AppBundleEntityCategory $categories */ public function removeCategory(AppBundleEntityCategory $categories) { $this->categories->removeElement($categories); } /** * Get categories * * @return DoctrineCommonCollectionsCollection */ public function getCategories() { return $this->categories; } } 这是Category实体(Category.php): <?php namespace AppBundleEntity; use DoctrineCommonCollectionsArrayCollection; use DoctrineORMMapping as ORM; use AppBundleEntityTag; /** * Category * * @ORMTable(name="category") * @ORMEntity(repositoryClass="AppBundleRepositoryCategoryRepository") */ class Category { /** * @var int * * @ORMColumn(name="Id",type="integer") * @ORMId * @ORMGeneratedValue(strategy="AUTO") */ protected $id; /** * * @var string * * @ORMColumn(name="CategoryName",type="string") */ protected $categoryname; /** * * @var string * * @ORMColumn(name="Description",type="string") */ protected $description; /** * @ORMManyToMany(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 AppBundleEntityTag $tags * @return Category */ public function addTag(AppBundleEntityTag $tags) { $this->tags[] = $tags; return $this; } /** * Remove tags * * @param AppBundleEntityTag $tags */ public function removeTag(AppBundleEntityTag $tags) { $this->tags->removeElement($tags); } /** * Get tags * * @return DoctrineCommonCollectionsCollection */ public function getTags() { return $this->tags; } } 这是控制器(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(); } $form_data是一个带有输入类别和添加标签详细信息的数组.它看起来像这样: $form_data = [ ['id' => 3,'categoryname' => 'gold'],[ ['id' => 1,'tagname' => 'wifi'],['id' => 4,'tagname' => 'geyser'],['id' => 2,'tagname' => 'cable'] ] ]; 它仍然没有坚持下去. var_dump($category);显示具有类别id和categoryname的所选类别对象,但关联的tags属性为空. 以下是输出的屏幕截图: 有任何想法吗? 旁边的快速问题:我是否需要在这里的关系定义的两侧添加cascade = {“persist”}? 编辑:在这里,我已经硬编码$form_data而不是像上面那样使用输入数据. DefaultController.php: /** * @Route("/formsubmit",name="my_route_to_submit") */ public function submitAction(Request $request) { $form_data = [ ['id' => 3,'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(); } 控制器输出: 如您所见,类别对象的tags属性仍为空. 希望这有助于更好地理解这个问题. 解决方法
通过执行获取适当的标记实体时
$tag = $em->getRepository('AppBundle:Tag')->findOneById($tagId); $tag的值是不是一个集合数组? 所以可能做以下事情? $category->addTag($tag[0]); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |