🎻

[Symfony] UniqueEntityで複合ユニークを設定した際に対象のフィールドすべてにエラーを表示する方法

2020/12/08に公開約2,600字

Symfony Advent Calendar 2020 の9日目の記事です!🎄🌙 小ネタですみません!

昨日は @77web さんでした✨

ちなみに、僕はよく TwitterにもSymfonyネタを呟いている ので、よろしければぜひ フォローしてやってください🕊🤲

本題です。

Doctrineを使うと以下のように @ORM\UniqueConstraint を使ってテーブルに複合ユニーク制約をかけることができますよね。

/**
 * @ORM\Entity(repositoryClass=FooRepository::class)
 * @ORM\Table(uniqueConstraints={
 *     @ORM\UniqueConstraint(name="foo_prop1_prop2_prop3_unique", columns={"prop1", "prop2", "prop3"})
 * })
 */
class Foo
{
    /**
     * @ORM\Column(type="string", length=255)
     */
    public ?string $prop1 = null;

    /**
     * @ORM\Column(type="string", length=255)
     */
    public ?string $prop2 = null;

    /**
     * @ORM\Column(type="string", length=255)
     */
    public ?string $prop3 = null;
    
    // ...
}

でもこのままだと制約違反のデータを作ろうとしたときにデータベースレイヤーのエラーになって例外がキャッチされないので、普通は @UniqueEntity バリデーションを設定すると思います。

/**
 * @ORM\Entity(repositoryClass=FooRepository::class)
 * @ORM\Table(uniqueConstraints={
 *     @ORM\UniqueConstraint(name="foo_prop1_prop2_prop3_unique", columns={"prop1", "prop2", "prop3"})
 * })
 * @UniqueEntity(fields={"prop1", "prop2", "prop3"}, message="prop1, prop2, prop3がすべて同一のFooを複数作成することはできません", errorPath="prop1")
 */
class Foo
{

これで、フォーム送信時にエラーが表示されるようにはなりますが、これだと prop1 のフォーム項目にしかエラーが表示されなくて、ちょっとUI的に親切じゃないですよね。

できれば prop1 prop2 prop3 すべてに同じエラーメッセージを表示したいなーと思うと思うんですが、実はめっちゃ簡単に対応できます。

/**
 * @ORM\Entity(repositoryClass=FooRepository::class)
 * @ORM\Table(uniqueConstraints={
 *     @ORM\UniqueConstraint(name="foo_prop1_prop2_prop3_unique", columns={"prop1", "prop2", "prop3"})
 * })
 * @UniqueEntity(fields={"prop1", "prop2", "prop3"}, message="prop1, prop2, prop3がすべて同一のFooを複数作成することはできません", errorPath="prop1")
 * @UniqueEntity(fields={"prop1", "prop2", "prop3"}, message="prop1, prop2, prop3がすべて同一のFooを複数作成することはできません", errorPath="prop2")
 * @UniqueEntity(fields={"prop1", "prop2", "prop3"}, message="prop1, prop2, prop3がすべて同一のFooを複数作成することはできません", errorPath="prop3")
 */
class Foo
{

シンプルに、これでOKです。 errorPath を変えて3行書くだけ。

意外と盲点じゃないですか?(僕は最初やり方分からなくて困ってましたw)

以上、どこかの誰かのお役に立てば幸いです!

Symfony Advent Calendar 2020、明日はまた僕です!笑 お楽しみに!

GitHubで編集を提案

Discussion

ログインするとコメントできます