Уникальные ограничения в доктрине 2, Symfony 2
Я хочу создать уникальное ограничение в моей сущности Doctrine 2 таким образом, чтобы name
и test
были уникальным столбцом. Значение
-
obj1
-
obj2
- имя: name2
- test: test < ---- duplicated
Это должно привести к ошибке при повторном тестировании.
Я попытался использовать уникальное ограничение (Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity
). Пробовал
* @UniqueEntity("name")
* @UniqueEntity("test")
и
* @UniqueEntity({"name", "test"})
Оба, кажется, только запускают ошибку, когда у меня есть имя BOTH и проверка дублируется. например.
Какая правильная настройка? Или я мог где-то совершить ошибку?
Возможно, я должен включить аннотацию доктрины, например:
@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) {
}
}
Но я получаю сообщение об ошибке на уровне базы данных об уникальном ограничении. Итак, как я должен получить уровень проверки, который работает?
Ответы
Ответ 1
Они проверяют поля отдельно:
@UniqueEntity("name")
@UniqueEntity("test")
То есть, первый будет запущен, когда будет дублируемое значение name
, а второе - при наличии дубликатов test
.
Если вы хотите, чтобы проверка завершилась неудачно, если оба name
и test
содержат одну и ту же комбинацию, вы используете это:
@UniqueEntity({"name", "test"})
Для чего вы хотите, чтобы первый подход работал - если вы не сделали что-то неправильно в другом месте. Также попробуйте очистить кеш, чтобы убедиться, что это не его ошибка.
UPDATE
То, что я предложил, касалось части проверки на стороне приложения. Если вы создаете схему базы данных с помощью Doctrine, вам нужно предоставить аннотации уровня Doctrine для каждого столбца - если вы хотите сделать их уникальными независимо друг от друга, конечно:
@Column(type = "string", unique = true)
private $name;
@Column(type = "string", unique = true)
private $test;
Эти подходы дополняют друг друга - не исключают. @UniqueEntity
гарантирует, что дубликат не достигнет уровня базы данных, а @Column
гарантирует, что если он это сделает, уровень базы данных не позволит ему пройти.
Ответ 2
В аннотации таблицы вы также можете установить индекс для нескольких столбцов .
/**
* @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]