Quería compartir la solución con aquellos que hayais tenido el problema que he tenido yo con hacer único un atributo de una entidad, como era mi caso con el atributo email
en mi entidad USUARIO
.
Siguiendo la documentación añadí en mi entidad las siguientes líneas para que al usuario que quisiera registrarse con un email utilizado le saltase una excepción en el formulario advirtiéndoselo:
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; /** * @ORM\Entity * @UniqueEntity("email") */ class Usuario implements AdvancedUserInterface { // ... /** * @var string * * @ORM\Column(name="email", type="string", length=255, unique=true) * @Assert\Email() */ protected $email;
Haciendo lo anterior, no llegaba a conseguir mi propósito ya que cuando intentaba registrarme con un email ya existente, me saltaba una excepción no controlada de tipo DuplicateEntry
y que en ningún caso era lo que quería:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '[email protected]' for key 'UNIQ_D8183973E7927C74'
Tras investigar he dado con la solución que pretendía, que era ni más ni menos que saltara un mensaje en el formulario del registro. Para lo anterior hay que modificar la línea del UniqueEntity
de la siguiente forma:
/** * @ORM\Entity * * @UniqueEntity(fields={"email"}, message="Este correo ya está siendo utilizado", * groups={"registro"}) */ class Usuario implements AdvancedUserInterface { // ... }
Siendo registro
el nombre que le hayamos dado al validation_groups
de la función setDefaultOptions
que tenemos implementado en el formType
.
Además, para aquellos que estén usando formularios embebidos, para hacer funcionar el @UniqueEntity
debéis añadir al método setDefaultOptions
mencionado la siguiente línea:
public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( // ... 'cascade_validation' => true, )); }
Respuestas
Con symfony2.2 igual me ocurre con
@Assert\Callback(methods={"formatoEmailCorrecto"})
que lo he debido cambiar a
@Assert\Callback(methods={"formatoEmailCorrecto"}, groups={"registro"})
para que realmente me funcione.
@Jorge_Gante
@Jorge_Gante creo que en este caso realmente no estamos hablando de un bug, sino de un pequeño desajuste en las anotaciones de la entidad. Por el código que muestras, supongo que validas la entidad con un código como el siguiente:
$validator->validate($usuario, array('registro'));
Sin embargo, en tu primer ejemplo la anotación estaba configurada de la siguiente manera:
/** * @ORM\Entity * @UniqueEntity("email") */ class Usuario implements AdvancedUserInterface { // ... }
Cuando una constraint de validación no tiene asignada un grupo, se supone que pertenece al grupo default
. Así que la restricción que hace que el email no pueda estar duplicado, pertenece al grupo default
y no al grupo registro
. Cuando validas la entidad con el código anterior, sólo se ejecutan las restricciones del grupo registro
, por lo que la restricción @UniqueEntity
no es que esté funcionando mal, es que ni siquiera se está ejecutando.
@javiereguiluz
Me he expresado mal, no es un bug. Más bien es una aspecto a tener en cuenta para hacer funcionar las constraint de validación de las entidades.
@Jorge_Gante