0

以下のように、多対多の関係(と呼​​ばれるリンクテーブル内blog_link_tags)を介して複数のタグが割り当てられているブログ投稿を更新するシナリオがあります。

...

$em = $this->getDoctrine()->getManager();
$blogPost = $em->getRepository('MyBlogBundle:Blog')->find($postId);


$blogPost
    ->setTitle( $request->request->get('post_title', '') )
    ->setBody( $request->request->get('post_body', '') )
    ->setLive(true);


$postTags = json_decode( $request->request->get('post_tags', '') );
$tagRepository = $em->getRepository('MyBlogBundle:BlogTag');

foreach($postTags as $postTag) {
    $tag = $tagRepository->find( $postTag->id );
    if (!$tag) {
        throw $this->createNotFoundException('Tag not found: ' . $tag->title);
    }
    $blogPost->addTag($tag);
}

$em->flush();

....

おそらくお分かりのように、ブログの投稿を編集して新しいタグを追加すると、重複するレコードが作成されます。

blog_link_tag現在のブログ投稿IDのレコードのテーブルを切り捨てるか、一意のタグIDのみを挿入するための最良の方法は何ですか?foreachループ内の次の行でそれを行うことでしょうか:

$tag = $tagRepository->find( $postTag->id );

しかし、代わりに、タグが存在するかどうか、およびタグがリンクテーブルにまだ存在していないかどうかを確認してください。それとも、Doctrine 2はそのような行動を達成するためのより良い方法を提供しますか?

4

2 に答える 2

2

$blogPostあなたはそれを所有する側であると仮定するための2つの解決策を持っています:

最初の解決策は、$blogPost->getTags()->clear()の前に使用しforeachます。これに注意すると、内のすべてのリンクされたタグが削除されますblog_link_tags。ただし、foreachに再度追加しても問題ありません。コンテンツによって異なります$postTags

if(!$blogPost->getTags()->contains($tag))2つ目は、前にテストすることです$blogPost->addTag($tag);

リレーションでArrayCollectionを処理していることを忘れないでくださいmany-to-many

NB: ここにタイプミスがあると思います:

 if (!$tag) {
        throw $this->createNotFoundException('Tag not found: ' . $tag->title);
    }

終了しない場合$tagは、を使用できません$tag->title。使いたかったと思います$postTag->title

于 2013-01-25T08:45:47.260 に答える
1

私に関する限り、最初にPostエンティティのFormTypeを作成します。これにより、コントローラーに厄介なコードを書き込む必要がなくなり、すべてが自動化され、クリーンで安全になります。

次に、Postエンティティ内のタグを次のように管理します。

class Post
{

    private $tags;

    public function __construct()
    {
        $this->tags = new ArrayCollection();
    }

    public function setTags($tags)
    {
        $this->tags->clear();

        foreach ($tags as $tag) {
            $this->addTag($tag);
        }

        return $this;
    }

    public function addTag(Tag $tag)
    {
         if (!$this->tags->contains($tag)) {
             $this->tags[] = $tag;
         }
    }
}
于 2013-01-25T14:06:39.317 に答える