【发布时间】:2016-11-13 08:26:39
【问题描述】:
我正在处理一个带有 2 个输入字段和一个提交按钮的表单。第一个字段是一个简单的下拉列表(类别),但另一个是标签输入字段(标签),您可以一次输入多个标签。这两个字段都只接受预定义的输入选项。
类别选项值在 javascript 中是硬编码的:
categories = [
{"id": 1, "categoryname": "standard"},
{"id": 2, "categoryname": "premium"},
{"id": 3, "categoryname": "gold"}
];
标签的选项是从数据库中的tag 表中获取的。这是数据库表的屏幕截图:
Category 和 Tag 实体与 Doctrine 的 ManytoMany 双向关系相关联,其中 category 是拥有方。
注意:我没有使用 Symfony formType 来创建表单,而是使用了 javascript。
javascript 工作正常,我在控制器中获取输入数据。 问题是我从来没有手动保持多对多关系。 确实阅读了文档,但不确定我是否遗漏了什么。
这是标签实体 (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;
}
}
这是类别实体 (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;
}
}
这里是控制器(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", 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();
}
控制器输出:
如您所见,类别对象的tags 属性仍为空。
希望这将有助于更好地理解问题。 等待回复...
【问题讨论】:
标签: php forms symfony doctrine-orm