我有一个用户注册表单。此表单必须执行的操作之一是强制新用户的电子邮件地址的唯一性。换句话说,新用户的电子邮件地址不能是其他人已经使用过的电子邮件地址。
我还没有找到一个可接受的解决方案来解决这个问题,这有点令人惊讶,因为这个需求是多么简单和普遍(以及Rails中解决方案的简单和简单!)。
我见过this question/answer,但该解决方案的问题在于它似乎不仅在创建记录时验证“唯一性”,而且每次尝试更新记录时也是如此。因此,一旦保存了记录,您就无法再次更新它,因为它告诉您电子邮件地址已被使用。 (也许我正在实施他们的解决方案,但它看起来并不像我。)
是否有人在实体/表单上有一个工作示例(不仅仅是docs的链接,我已经阅读过了)一个唯一性验证器?
答案 0 :(得分:17)
好的,我有它的工作。我曾经在所有用户表单上“验证”电子邮件唯一性的问题,无论我是否希望在那里进行检查,这是我能够通过验证组解决的问题。这是我的User
实体的相关部分。请注意groups={"registration"}
注释的@UniqueEntity
部分:
/**
* VNN\PressboxBundle\Entity\User
*
* @ORM\Table(name="user")
* @ORM\Entity
* @UniqueEntity(fields="email", message="Sorry, this email address is already in use.", groups={"registration"})
* @UniqueEntity(fields="username", message="Sorry, this username is already taken.", groups={"registration"})
*/
class User implements AdvancedUserInterface, \Serializable
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var string $email
* @Assert\NotBlank()
* @Assert\Email()
*
* @ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* @var string $username
* @Assert\NotBlank()
*
* @ORM\Column(name="username", type="string", length=255, unique=true)
*/
private $username;
我的表单类(注意最后一个函数):
<?php
namespace VNN\PressboxBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder
->add('first_name')
->add('last_name')
->add('email')
->add('username')
->add('password', 'password')
->add('athletic_director_email')
->add('school')
->add('active', 'hidden')
->add('transition_key', 'hidden')
;
}
public function getName()
{
return 'vnn_pressboxbundle_usertype';
}
// The following function is what's important here.
// This tells this form to use the "registration" validation group.
public function getDefaultOptions(array $options)
{
return array(
'validation_groups' => array('registration')
);
}
}
我相信就是这样。我不认为我必须在其他地方做任何特别的事情。
答案 1 :(得分:0)
您可以对其进行硬编码,例如
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($existingUser = $this->getDoctrine()->getRepository('AppBundle:User')->findOneBy(['email' => trim($form->getData()->getEmail())])) {
$form->get('email')->addError(new FormError('Email already used'));
}
}
答案 2 :(得分:-1)
如果您使用的是Doctrine,您是否可以尝试直接在实体中设置唯一标志?
/**
* @ORM\Column(type="string", unique="true")
*/
protected $email;