Je veux créer une contrainte unique dans mon Doctrine 2 entité de telle sorte que name
& test
sont des colonnes uniques. Signification
obj1
obj2
Cela devrait déclencher une erreur lorsque le test est dupliqué.
J'ai essayé d'utiliser la contrainte unique (Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity
). A tenté
* @UniqueEntity("name")
* @UniqueEntity("test")
et
* @UniqueEntity({"name", "test"})
Les deux semblent déclencher une erreur uniquement lorsque j'ai le nom et le test en double. par exemple.
obj1
obj2
Quelle est la bonne configuration? Ou j'ai peut-être fait une erreur quelque part?
Je devrais peut-être inclure l'annotation doctrine comme:
@Table(name="ecommerce_products",uniqueConstraints={@UniqueConstraint(name="search_idx", columns={"name", "email"})})
Mais cela ne gérera toujours pas ma validation de formulaire symfony je pense?
MISE À JOUR
Mon code de test:
/**
* @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();
Lors de la première exécution (table vide):
=== 1 ===object(Symfony\Component\Validator\ConstraintViolationList)#322 (1) {
["violations":protected]=>
array(0) {
}
}
=== 2 ===object(Symfony\Component\Validator\ConstraintViolationList)#289 (1) {
["violations":protected]=>
array(0) {
}
}
Mais j'obtiens une erreur sur la couche de base de données sur la contrainte unique. Alors, comment dois-je faire fonctionner la couche de validation?
Ceux-ci vérifient les champs individuellement:
@UniqueEntity("name")
@UniqueEntity("test")
Autrement dit, le premier sera déclenché lorsqu'il y a une valeur name
en double, tandis que le second - lorsqu'il y a une valeur test
en double.
Si vous voulez que la validation échoue lorsque les deux name
et test
contiennent les mêmes combinaison , vous utilisez ceci:
@UniqueEntity({"name", "test"})
Pour ce que vous voulez, la première approche devrait fonctionner - sauf si vous avez fait quelque chose de mal ailleurs. Essayez également de vider le cache pour vous assurer que ce n'est pas de sa faute.
MISE À JOUR
Ce que j'ai suggéré concernait la partie validation du côté de l'application. Si vous générez le schéma de base de données à l'aide de Doctrine, vous devrez fournir les annotations de niveau Doctrine) pour chaque colonne - si vous voulez les rendre uniques indépendamment les uns des autres, bien sûr:
@Column(type = "string", unique = true)
private $name;
@Column(type = "string", unique = true)
private $test;
Ces approches se complètent - ne s'excluent pas. @UniqueEntity
s'assure qu'un doublon n'atteint même pas la couche de base de données, tandis que @Column
garantit que si c'est le cas, la couche de base de données ne la laissera pas passer.
Dans l'annotation Table, vous pouvez également définir un index pour plusieurs colonnes .
/** * @ORM\Entity * @ORM\Table (name = "ecommerce_products", uniqueConstraints = { * @ORM\UniqueConstraint (name = "search_idx", colonnes = {"nom", "email"})}) */
ou au format YAML:
Namespace\Entity\EntityName:
type: entity
table: ecommerce_products
uniqueConstraints:
uniqueConstraint:
columns: [name, email]