Правило Unique
Правило Unique относится к ограничениям
валидации формы. Оно вешается на поле и проверяет,
что введённое значение не совпадает со значением
этого же поля у других записей. Это ограничение
работает на уровне сущности Doctrine: ему нужно
указать класс сущности и поле, по которому
проверяется уникальность.
Чаще всего правило применяют к полям вроде логина,
email или slug. Первым параметром передаётся
имя поля, по которому идёт поиск дублей. Для
обновления существующей записи можно передать
id в опции ignore, чтобы сущность
не считалась дублем самой себя.
Синтаксис
new Unique(
entityClass: ClassName::class,
field: 'fieldName'
)
Пример
Давайте создадим сущность User с полем
email и повесим на него правило
Unique:
<?php
namespace AppEntity;
use DoctrineORMMapping as ORM;
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
use SymfonyComponentValidatorConstraints as Assert;
#[ORMEntity]
#[UniqueEntity(fields: ['email'], message: 'Email already exists')]
class User
{
#[ORMId]
#[ORMGeneratedValue]
#[ORMColumn]
private ?int $id = null;
#[ORMColumn(length: 255, unique: true)]
#[AssertNotBlank]
#[AssertEmail]
private string $email = '';
public function getId(): ?int
{
return $this->id;
}
public function getEmail(): string
{
return $this->email;
}
public function setEmail(string $email): self
{
$this->email = $email;
return $this;
}
}
?>
Теперь создадим форму с полем email и
правилом Unique:
<?php
namespace AppForm;
use AppEntityUser;
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
use SymfonyComponentFormAbstractType;
use SymfonyComponentFormExtensionCoreTypeEmailType;
use SymfonyComponentFormFormBuilderInterface;
use SymfonyComponentOptionsResolverOptionsResolver;
use SymfonyComponentValidatorConstraints as Assert;
class UserType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('email', EmailType::class, [
'constraints' => [
new AssertNotBlank(),
new AssertEmail(),
new UniqueEntity([
'entityClass' => User::class,
'field' => 'email',
'message' => 'This email is already taken',
]),
],
]);
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
?>
Результат выполнения кода при попытке сохранить уже существующий email:
"This email is already taken"
Пример
Давайте проверим уникальность поля email
через валидатор напрямую:
<?php
namespace AppController;
use AppEntityUser;
use SymfonyBundleFrameworkBundleControllerAbstractController;
use SymfonyBridgeDoctrineValidatorConstraintsUniqueEntity;
use SymfonyComponentHttpFoundationResponse;
use SymfonyComponentRoutingAttributeRoute;
use SymfonyComponentValidatorValidatorValidatorInterface;
class UserController extends AbstractController
{
#[Route('/user/check', name: 'user_check')]
public function check(ValidatorInterface $validator): Response
{
$user = new User();
$user->setEmail('abcde');
$errors = $validator->validate($user);
if (count($errors) > 0) {
return new Response((string) $errors);
}
return new Response('valid');
}
}
?>
Результат выполнения кода, если email уже занят:
"This email is already taken"
Результат выполнения кода, если email свободен:
"valid"
Смотрите также
-
правило
UniqueEntity,
которое проверяет уникальность сущности -
правило
NotBlank,
которое проверяет, что поле не пустое -
правило
Email,
которое проверяет корректность email -
класс
Form,
который представляет форму в Symfony