Validateur UniqueEntity et héritage Doctrine

26.09.2014  • Samuel Breton

Le validateur UniqueEntity fourni dans la standard edition de Symfony2 permet de vérifier l’unicité d’un ou plusieurs champs d’une entité. Très simple à mettre en place, son utilisation se complique un peu dans le cas d’un champ commun partagé dans un héritage.

Cas simple : une seule classe “User”

Imaginons une classe User toute simple, dont la propriété username doit être unique :

Validation

Tentons d’assigner le même username à deux User différents : le validateur détecte la duplicité et remonte une erreur.

Cas complexe : 2 classes “Patient” et “Doctor” héritant de “User”

Imaginons maintenant que nous ayons 2 types d’utilisateurs : Doctor et Patient, qui étendent notre classe User d’origine où se trouve le champ username à valider.

Mettons en place un héritage doctrine (de type Class Table Inheritance) :

Idem pour l’entité Doctor.

Validation

Tentons d’assigner le même username à deux Doctor ou à deux Patient : le validateur détecte la duplicité et renvoie une erreur. Essayons maintenant de donner le même username à un Patient et à un Doctor : le validateur ne détecte pas d’erreur.

Problème

En interne, le validateur utilise la méthode findBy du repository de l’entité à valider. Dans le cas d’un héritage doctrine, cette méthode filtre les entités à valider en se basant sur leur discriminant, et ne prend donc pas en compte les autres entités filles.

Solution

Changeons ce fonctionnement en implémentant notre propre méthode, disons findByUsername.

À noter La méthode findByUsername doit être implémentée dans le repository de chaque classe fille et renvoyer des objets hydratés afin de pouvoir les comparer.

Pour cet exemple, nous allons créer un UserRepository dont les DoctorRepository et PatientRepository hériteront :

Idem pour le repository DoctorRepository.

Il ne reste plus qu’à spécifier au validateur la méthode du repository à utiliser. Dans notre cas c’est au niveau de l’annotation UniqueEntity déclarée dans la classe User parent :

Voilà, en espérant que ça vous aidera !

Directeur conseil chez Spiriit
J'accompagne nos clients sur la mise en place de la stratégie, de l'architecture et dans la structuration du projet. J'interviens en amont des projets pour la planification et en aval sur la partie KPI / Performance.
Voir l’étude de cas
Lire l’article
Lire l’actualité
En savoir plus
En savoir plus
Voir le témoignage
Fermer