Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unique validator in Symfony2

Tags:

symfony

I have a user sign-up form. One of the things this form must do is enforce the uniqueness of the new user's email address. In other words, the new user's email address must not be an email address already used by someone else.

I haven't yet been able to find an acceptable solution to this problem, which is somewhat surprising given how simple and common this need is (and how simple and easy the solution is in Rails!).

I've seen this question/answer, but the problem with that solution is that it seems to validate "uniqueness" not only on the creation of a record, but every time you try to update the record as well. So once a record is saved, you can't update it ever again because it tells you the email address is already being used. (Perhaps I'm implementing their solution wrong, but it doesn't seem like I am.)

Does anyone have a working example (not just a link to the docs, please, which I've already read) of a uniqueness validator on an entity/form?

like image 269
Jason Swett Avatar asked Jun 02 '12 15:06

Jason Swett


1 Answers

Okay, I have it working. The problem I had been having with email uniqueness being "validated" on all user forms, regardless of whether or not I wanted it to be checked there, was something I was able to solve with validation groups. Here's the relevant part of my User entity. Notice the groups={"registration"} part of the @UniqueEntity annotations:

/**
 * 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;

And my form class (note the last function):

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

And I believe that's it. I don't think I had to do anything special anywhere else.

like image 151
Jason Swett Avatar answered Nov 03 '22 18:11

Jason Swett