私はDoctrine 2エンティティでname
&test
が列ごとに一意であるように一意の制約を作成します。
obj1
obj2
テストが複製されると、エラーが発生します。
一意の制約(Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity
)。試した
* @UniqueEntity("name")
* @UniqueEntity("test")
そして
* @UniqueEntity({"name", "test"})
両方とも、名前とテストの両方が重複している場合にのみエラーをトリガーするようです。例えば。
obj1
obj2
適切なセットアップは何ですか?それとも、どこかでミスをしたかもしれませんか?
おそらくdoctrineアノテーションを含める必要があります:
@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})
しかし、それでもsymfonyのフォーム検証を処理できないと思いますか?
[〜#〜] update [〜#〜]
私のテストコード:
/**
* @ORM\Entity
* @ORM\Table(name="roles")
* @UniqueEntity("name")
* @UniqueEntity("test")
*/
class Role {
/**
* @var integer
* @ORM\Column(type="integer")
* @ORM\Id
* @ORM\GeneratedValue
*/
protected $id;
/**
* @var string
*
* @ORM\Column(type="string", length=32, unique=true)
* @Assert\MaxLength(32)
* @Assert\Regex("/^[a-zA-Z0-9_]+$/")
*/
protected $name;
}
$v = $this->get('validator');
$role = new Role();
$role->setName('jm');
$role->setTest('test');
$e = $v->validate($role);
echo '=== 1 ===';
var_dump($e);
if (count($e) == 0)
$em->persist($role);
$role2 = new Role();
$role2->setName('john');
$role2->setTest('test');
$e = $v->validate($role2);
echo '=== 2 ===';
var_dump($e);
if (count($e) == 0)
$em->persist($role2);
$em->flush();
最初の実行時(空のテーブル):
=== 1 ===object(Symfony\Component\Validator\ConstraintViolationList)#322 (1) {
["violations":protected]=>
array(0) {
}
}
=== 2 ===object(Symfony\Component\Validator\ConstraintViolationList)#289 (1) {
["violations":protected]=>
array(0) {
}
}
ただし、データベース層で一意制約に関するエラーが発生します。では、検証レイヤーをどのように動作させる必要がありますか?
これらはフィールドを個別にチェックします。
@UniqueEntity("name")
@UniqueEntity("test")
つまり、最初の1つはname
値が重複するときにトリガーされ、2つ目はtest
値が重複するときにトリガーされます。
bothname
とtest
が同じcombinationを含むときに検証を失敗させる場合、これを使用します:
@UniqueEntity({"name", "test"})
あなたが望むもののために、最初のアプローチはうまくいくはずです-あなたが他のどこかで間違ったことをしない限り。また、キャッシュをクリアして、障害ではないことを確認してください。
[〜#〜] update [〜#〜]
私が提案したのは、アプリ側の検証部分についてでした。 Doctrineを使用してデータベーススキーマを生成する場合、each列にDoctrineレベルアノテーションを提供する必要があります—それらを作成する場合もちろん、互いに独立して一意です:
@Column(type = "string", unique = true)
private $name;
@Column(type = "string", unique = true)
private $test;
これらのアプローチは互いに補完するものであり、排除するものではありません。 @UniqueEntity
は、複製がデータベース層に到達しないことを確認しますが、@Column
は、もしそうなら、データベース層が通過させないことを保証します。
テーブルアノテーションでは、複数の 列 のインデックスを設定することもできます。
/** * @ORM\Entity * @ORM\Table(name = "ecommerce_products"、uniqueConstraints = { * @ORM\UniqueConstraint(name = "search_idx"、columns = {"name"、 "email"})}) */
またはYAML形式の場合:
Namespace\Entity\EntityName:
type: entity
table: ecommerce_products
uniqueConstraints:
uniqueConstraint:
columns: [name, email]