【问题标题】:Unique validator in Symfony2Symfony2 中的唯一验证器
【发布时间】:2012-06-02 15:17:41
【问题描述】:

我有一个用户注册表单。此表单必须做的一件事是强制新用户电子邮件地址的唯一性。也就是说,新用户的邮箱地址不能是已经被其他人使用过的邮箱地址。

我还没有找到一个可接受的解决方案来解决这个问题,考虑到这种需求是多么简单和普遍(以及在 Rails 中解决方案是多么简单和容易!),这有点令人惊讶。

我见过this question/answer,但该解决方案的问题在于,它似乎不仅在创建记录时验证“唯一性”,而且每次尝试更新记录时也是如此。因此,一旦保存记录,您将无法再次更新它,因为它会告诉您该电子邮件地址已被使用。 (也许我执行他们的解决方案是错误的,但我似乎不是。)

是否有人有实体/表单上唯一性验证器的有效示例(不仅仅是指向docs 的链接,我已经阅读过)?

【问题讨论】:

标签: symfony


【解决方案1】:

好的,我已经成功了。无论我是否希望在所有用户表单上“验证”电子邮件唯一性,我一直遇到的问题是我能够通过验证组解决的问题。这是我的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')
        );  
    }   
}

我相信就是这样。我认为我不必在其他任何地方做任何特别的事情。

【讨论】:

  • 您可能需要考虑的唯一额外事情是用户想要更改其电子邮件的情况。
  • 这仅在您执行持久化 + 刷新并捕获 DoctrineException 时有效,即使用户的用户名已经存在于数据库中,$form->handleRequest() 也可以将 isValid() 返回为 true .
【解决方案2】:

你可以硬编码,比如

$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'));
     }
}

【讨论】:

    【解决方案3】:

    如果你使用Doctrine,你可以尝试直接在Entity中设置唯一标志吗?

    /**
     * @ORM\Column(type="string", unique="true")
     */
    protected $email;
    

    【讨论】:

    • 此标志仅适用于数据库。它创建一个唯一的密钥,但没有验证。如果保存条目,您将收到以下错误:完整性约束违规:1062 重复条目
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-27
    • 2012-07-31
    • 2017-09-20
    • 1970-01-01
    相关资源
    最近更新 更多