2011-12-13 19 views
5

Sto tentando di convalidare l'unicità di un'entità inoltrata da un modulo utilizzando il vincolo di convalida UniqueEntity su più campi.Symfony2 UniqueEntity campi multipli: convalida falsi positivi?

Codice del soggetto che dovrebbe essere unico ha due campi - FieldA e FieldB, entrambi unici:

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

Supponiamo che ho già un record nel database con i valori:

  • campoA = 'valore_a', campoB = 'valore_b'

Ora, quando provo ad inviare un altro con valori (FieldA = 'value_a', FieldB = 'value_c') da un modulo, Symfony2 genera una query per verificare l'unicità:

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

e la convalida passa, perché il risultato è un set vuoto, ma Mi aspetterei che fallisca, perché fieldA non sarà univoco in questo caso. (L'inserto SQL non riesce con un errore voce duplicata su 'value_a'.)

Symfony2's UniqueEntity documentation says:

Questa opzione obbligatoria è il campo (o l'elenco dei campi) su cui questa entità deve essere univoco. Ad esempio, è possibile specificare che sia l'e-mail sia i campi nome nell'esempio Utente sopra devono essere unici.

Penso che confermi le mie aspettative.

Ho scoperto in the source of UniqueEntityValidator (line 94), che il validatore prende i campi come una matrice e utilizza il metodo finder "findBy" per verificare l'unicità. Questo metodo utilizza la relazione "AND" tra i parametri nella query, che causa il problema.

È possibile utilizzare questo vincolo di convalida per il mio problema in qualche modo o devo convalidarlo in un altro modo?

risposta

8

Che dire:

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

?

+0

Grazie, si fa il lavoro! L'unico problema è che ogni asserita richiede un'altra query, ma penso di poter conviverci. – csabavegso

+1

Altrimenti, hai sempre la soluzione per scrivere il tuo Validatore, con l'ispirazione del Validatore UniqueEntity – webda2l

13

dovrebbe essere:

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

Facendo

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

si verificherà se non ci sono righe con entrambi i campi lo stesso.

Quindi supponiamo si dispone già di un record nel database con i valori:

fieldA = 'value_a', fieldB = 'value_b' 

Ora, quando si tenta di inviare un altro con valori (FieldA = 'value_a', FieldB = 'value_c') da un modulo , Symfony2 genera una query per verificare l'unicità:

SELEZIONA ... DA ... DOVE campoA =?AND fieldB =? ('Value_a', 'value_c')

e questo passerà, perche 'non corrisponde una riga con

fieldA = 'value_a', fieldB = 'value_b' 

solo quando yo presentare un'altra con valori (FieldA = 'value_a', FieldB = 'value_b') da un modulo, la validazione non passerà.

Questo è il modo in cui dovrebbe funzionare e come viene spiegato nella documentazione: http://symfony.com/doc/current/reference/constraints/UniqueEntity.html#fields

Problemi correlati