2011-12-13 16 views
5

Estoy tratando de validar la exclusividad de una entidad enviada desde un formulario mediante el uso de Restricción de validación de UniqueEntity en múltiples campos.Symfony2 UniqueEntity campos múltiples: ¿validación positiva falsa?

Código de la entidad que debe ser único tiene dos campos - FIELDA y FIELDB, tanto únicas:

/** 
* @ORM\Table(name="mytable") 
* @ORM\Entity 
* @DoctrineAssert\UniqueEntity(fields = {"fieldA", "fieldB"}) 
*/ 
class myClass 
{ 
    /** 
    * @ORM\Column(name="fieldA", type="string", length=128, unique=true) 
    */ 
    protected $fieldA; 

    /** 
    * @ORM\Column(name="fieldB", type="string", length=128, unique=true) 
    */ 
    protected $fieldB; 
} 

Supongamos que ya tiene un registro en la base de datos con valores:

  • fieldA = 'value_a', fieldB = 'value_b'

Ahora cuando intento enviar otro con los valores (FIELDA = 'value_a', FIELDB = 'value_c') de un formulario, Symfony2 genera una consulta para comprobar la singularidad:

SELECT ... FROM ... WHERE fieldA = ? AND fieldB = ? ('value_a', 'value_c') 

y pasa la validación, ya que el el resultado es un conjunto vacío, pero esperaría que fallara, porque fieldA no será único en este caso. (La inserción de SQL falla con un error de entrada duplicada en 'value_a'.)

Symfony2's UniqueEntity documentation says:

Esta opción requerida es el campo (o lista de campos) en la que esta entidad debe ser único. Por ejemplo, puede especificar que los campos de nombre y correo electrónico en el ejemplo de usuario anterior sean únicos.

Creo que confirma mis expectativas.

Descubrí in the source of UniqueEntityValidator (line 94), que el validador toma los campos como una matriz, y utiliza el método de búsqueda mágica "findBy" para verificar la singularidad. Este método usa la relación 'Y' entre los parámetros en la consulta, lo que causa el problema.

¿Es posible utilizar esta restricción de validación para mi problema de alguna manera, o tengo que validarlo de otra manera?

Respuesta

8

¿Qué hay de:

/** 
* @ORM\Table(name="mytable") 
* @ORM\Entity 
* @DoctrineAssert\UniqueEntity(fields = "fieldA") 
* @DoctrineAssert\UniqueEntity(fields = "fieldB") 
*/ 
class myClass 

?

+0

Gracias, que hace el trabajo! El único problema es que cada afirmación toma otra consulta, pero creo que puedo vivir con ella. – csabavegso

+1

De lo contrario, siempre tiene la solución para escribir su propio Validador, con la inspiración del Validador de UniqueEntity – webda2l

13

que debe ser:

/** 
* @ORM\Table(name="mytable") 
* @ORM\Entity 
* @DoctrineAssert\UniqueEntity(fields = "fieldA") 
* @DoctrineAssert\UniqueEntity(fields = "fieldB") 
*/ 
class myClass 

Haciendo

* @DoctrineAssert\UniqueEntity(fields = {"fieldA", "fieldB"}) 

se comprobará si no hay filas con dos campos del mismo.

Así que supongo que ya tiene un registro en la base de datos con los valores:

fieldA = 'value_a', fieldB = 'value_b' 

Ahora, cuando intenta enviar otro con los valores (FIELDA = 'value_a', FIELDB = 'value_c') a partir de un formulario , Symfony2 genera una consulta para verificar la exclusividad:

SELECCIONAR ... FROM ... WHERE fieldA =?AND fieldB =? ('Value_a', 'value_c')

y esto va a pasar, porque no coincide con una fila con

fieldA = 'value_a', fieldB = 'value_b' 

sólo cuando yo enviar otro con los valores (FIELDA = 'value_a', FIELDB = 'value_b') de un formulario, la validación no pasará.

Ésta es la forma en que debe trabajar y cómo se explica en la documentación: http://symfony.com/doc/current/reference/constraints/UniqueEntity.html#fields

Cuestiones relacionadas