我拥有多对多关系的Post
和Tag
个实体。在Post
创建和编辑表单中,有一个文本框,我可以在其中输入以与该帖子相关的逗号分隔的标记。例如,当我输入tag1,tag2,tag3以及带有标题' Post1'的帖子时,表单将创建帖子和标签实体,并将这些标签添加到该帖子的标签列表中。我使用数据转换器来创建标签实体。
class Post{
/**
* @ORM\ManyToMany(targetEntity="Tag", mappedBy="posts",cascade={"all"})
*/
protected $tags;
public function __construct() {
$this->tags = new ArrayCollection();
}
/**
* @return ArrayCollection
*/
public function getTags()
{
return $this->tags;
}
/**
* @param Tag $tag
*/
public function addTag(Tag $tag)
{
$tag->addPost($this);
$this->tags->add($tag);
}
/**
* @param Tag $tag
*/
public function removeTag(Tag $tag)
{
$this->tags->removeElement($tag);
}
}
PostType
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('title', TextType::class, array('label' => 'Title'))
->add('tags', TextType::class, array('label' => 'Tags'))
;
$builder->get('tags')
->addModelTransformer(new TagViewTransformer($this->manager));
}
TagViewTransformer
class TagViewTransformer implements DataTransformerInterface
{
public function transform($value)
{
/...
}
public function reverseTransform($value)
{
$tags = array();
if ( $value )
{
if( strpos($value, ',') !== false )
{
$list = array_unique(explode(",", $value));
}
else
{
$list = array(trim($value));
}
foreach ( $list AS $tagName )
{
$tag = $this->em
->getRepository('CoreBundle:Tag')
->findOneBy(array('name' => trim($tagName)));
if( !$tag )
{
$tag = new Tag();
$tag->setName(trim($tagName));
$this->em->persist($tag);
}
$tags[] = $tag;
}
}
return $tags;
}
}
当我尝试创建Post时,这很好用,所有标签都转换为实体并添加到Post的标签列表中。但是当我尝试编辑时,我开始遇到问题
public function editAction(Request $request, Post $post)
{
$deleteForm = $this->createDeleteForm($post);
$editForm = $this->createForm(PostType::class, $post);
$editForm->handleRequest($request);
$originalTags = $post->getTags();
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$newTags = $editForm->get('tags')->getData();
foreach ($originalTags as $currentTag) {
if (!in_array($currentTag, $newTags)) {
$post->removeTag($currentTag);
}
}
$em->persist($post);
$em->flush();
return $this->redirectToRoute('post_show', array('id' => $post->getId()));
}
return $this->render('AppBundle:Post:edit.html.twig', array(
'entity' => $post,
'form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
我们假设Post有标签:tag1, tag2, tag3
,但我想删除tag3
并添加tag4
。因此,我会将标签文本框更改为tag1, tag2, tag4
。但是,当我提交表单时,我会得到tag1, tag2, tag3, tag4
。所以tag3不会从Post的标签列表中删除。
editAction代码有什么问题?
答案 0 :(得分:0)
试试这个
public function editAction(Request $request, Post $post)
{
$deleteForm = $this->createDeleteForm($post);
$editForm = $this->createForm(PostType::class, $post);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($post);
$em->flush();
return $this->redirectToRoute('post_show', array('id' => $post->getId()));
}
return $this->render('AppBundle:Post:edit.html.twig', array(
'entity' => $post,
'form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
答案 1 :(得分:0)
使用Orphan removal执行此操作:
class Post
{
/**
* @ORM\ManyToMany(targetEntity="Tag", mappedBy="posts", cascade={"all"}, orphanRemoval=true)
*/
protected $tags;
/* Rest of your class */
}
做一些测试,可能在这里没有必要级联。