2017-02-28 18 views
0

多対多の関係を持つPostTagエンティティがあります。 Postフォームの作成と編集には、その記事に関連するコンマで区切られたタグを入力できるテキストボックスがあります。たとえば、「Post1」というタイトルのポストにtag1、tag2、tag3を入力すると、フォームはポストとタグエンティティを作成し、これらのタグをそのポストのタグリストに追加します。データトランスフォーマを使用してタグエンティティを作成します。Symfony:多対多更新

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; 
    } 
} 

私はポストを作成しようとすると、これは正常に動作し、すべてのタグがエンティティに変換され、ポストのタグリストに追加されます。私が編集しようとするけど、私は問題

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(), 
    )); 
} 

のポストは、タグがあるとしましょう

持ち始める: tag1, tag2, tag3を、私は tag3を削除し、 tag4を追加したいです。だから、私はタグのテキストボックスを tag1, tag2, tag4に変更します。しかし、私が書式を提出するとき、私は tag1, tag2, tag3, tag4を得る。したがって、tag3はPostのタグリストから削除されません。

editActionコードで何が問題になっていますか?

答えて

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(), 
    )); 
} 
0

使用Orphan removalで試してみてください。

class Post 
{ 
    /** 
    * @ORM\ManyToMany(targetEntity="Tag", mappedBy="posts", cascade={"all"}, orphanRemoval=true) 
    */ 
    protected $tags; 

    /* Rest of your class */ 

} 

いくつかのテストを行いますが、多分カスケード全てはここでは必要ではありません。

関連する問題