1

私は SF2 を学んでいます - やり遂げた仕事に本当に感銘を受け、自分では解決できない最初の本当の問題に直面しました。

投稿とタグの 2 つのエンティティがあります。以下の短縮コード:

class Tag
{
    /**
     * @ORM\ManyToMany(targetEntity="Post", mappedBy="tags", cascade={"persist"})
     */
    private $posts;

    public function __construct()
    {
        $this->posts = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * @param \My\AppBundle\Entity\Snippet $posts
     * @return Tag
     */
    public function addSnippet(\My\AppBundle\Entity\Post $posts)
    {
        $this->posts[] = $posts;

        return $this;
    }

    /**
     * @param \My\AppBundle\Entity\Snippet $snippets
     */
    public function removeSnippet(\My\AppBundle\Entity\Post $posts)
    {
        $this->posts->removeElement($posts);
    }

    /**
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getSnippets()
    {
        return $this->posts;
    }
}

class Post
{
    /**
     * @ORM\ManyToMany(targetEntity="Tag", inversedBy="posts", cascade={"persist"})
     * @ORM\JoinTable(name="posts_tags",
     *     joinColumns={@ORM\JoinColumn(name="post_id", referencedColumnName="id", unique=true, onDelete="cascade")},
     *     inverseJoinColumns={@ORM\JoinColumn(name="tag_id", referencedColumnName="id", unique=true, onDelete="cascade")}
     * )
     */
    private $tags;

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

    /**
     * @param \My\AppBundle\Entity\Tag $tags
     * @return Snippet
     */
    public function addTag(\My\AppBundle\Entity\Tag $tags)
    {
        $this->tags[] = $tags;

        return $this;
    }

    /**
     * @param \My\AppBundle\Entity\Tag $tags
     */
    public function removeTag(\My\AppBundle\Entity\Tag $tags)
    {
        $this->tags->removeElement($tags);
    }

    /**
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getTags()
    {
        return $this->tags;
    }
}

ご覧のとおり、2 つのエンティティ間に M:M の関係があります。

タグ コレクションが埋め込まれた Post を追加するフォームもあります。

        $builder
            ->add('title')
            ->add('tags', 'collection', array(
                'type' => new \My\AppBundle\Form\TagType(),
                'allow_add' => true,
                'by_reference' => false,
                'prototype' => true
            ))
        ;

TagType フォーム クラス:

$builder->add('name');

すべてが期待どおりに機能します。1 つ例外があります。次の名前の Tag オブジェクトがある場合、SQLSTATE[23000]: Integrity constraint violation明らかな MySQL エラーが発生します。一意の検証制約を適用すると、タグを投稿に追加できます (データベースに既に存在する場合)。

次のタグがデータベースに存在するかどうかを確認し、存在しない場合にのみ追加する必要があることは明らかですが... Symfonyの方法でそれを行う方法は?

どんな提案でも大歓迎です!

4

1 に答える 1

1

UniqueEntityを使用してこれを処理できます。タグクラスの注釈、または「名前」の宣言が表示されませんが、以下のようなものを追加すると、名前に基づいて一意の検証制約が与えられ、オプションのメッセージが返されます。

/**
 * @ORM\Entity
 * @UniqueEntity(fields="name", message="This tag name already exists")
 */
class Tag...

/**
 * @var string $name
 *
 * @ORM\Column(name="name", type="string", length=255, unique=true)
 */
protected $name;
于 2013-01-07T11:28:44.693 に答える