2010-10-14 3 views
22

Voici ce que je voudrais faire:Comment ajouter des contraintes sur les propriétés héritées dans un domaine Grails sous-classe

class A { 
    String string 
    static constraints = { 
    string(maxSize:100) 
    } 
} 

class B extends A { 
    static constraints = { 
    string(url:true) 
    } 
} 

Ainsi la classe A devrait avoir quelques contraintes et B devraient avoir les mêmes plus contraintes supplémentaires sur la même propriété.

Je ne pouvais pas obtenir que cela fonctionne et je peux imaginer qu'il serait incompatible avec le concept de Table par Hiérarchie. J'ai donc essayé de contourner ce problème en introduisant un objet Command avec des contraintes de classe B qui peuvent être validées dans le constructeur de la classe B. Cependant, il semble que les objets Command ne peuvent être utilisés que dans les contrôleurs (les grails ne cessent de dire n'est pas une méthode .validate() pour cela). Donc, ma question est: Quelle est la manière la plus élégante de résoudre cela en utilisant des contraintes de grails (ne pas ré-implémenter la validation manuellement)? Pourrait être ...

  • Passage au concept de la table par sous-classe?
  • Rendre l'objet de commande fonctionne dans la classe de domaine en quelque sorte?
  • Tout autre moyen?

Edit: Ce serait bien pour moi de définir toutes les contraintes dans les classes d'enfants, en répétant les contraintes de la classe mère ou même pas ayant des contraintes dans la classe parente du tout. Mais la solution devrait fonctionner pour plusieurs classes enfants (avec des contraintes différentes) de la même classe parente.

+0

Je ne suis pas sûr que chaque contrainte fonctionne de cette façon, comme par les classes héritées par défaut sont mis en correspondance avec une même table de DB. Donc, si vous avez la classe C avec des contraintes uniques non-nulles sur C.c, il imposera une contrainte de table DB sur toute la table A - et le champ c sera là pour toutes les classes, et sera nul pour autre chose que C instances. –

+0

Oui, c'est pourquoi j'ai mis en scène Table-per-Sub-Class. –

Répondre

5

La façon dont il était 2.x:

Comme contraintes est une fermeture exécutée par une ConstraintsBuilder, je vais essayer de l'appeler B, comme

class B extends A { 
    static constraints = { 
    url(unique: true) 
    A.constraints.delegate = delegate # thanks Artefacto 
    A.constraints() 
    } 
} 
+1

Fermez. Vous devez d'abord changer le délégué de 'A.constraints':' A.constraints.delegate = delegate'. Mais merci de m'indiquer dans la bonne direction. – Artefacto

+2

@Artefacto - Seriez-vous capable de poster une réponse qui fonctionne, ou de modifier cette réponse pour la faire fonctionner? Je connais d'autres personnes qui ont eu cette question. Merci! – cdeszaq

+0

je l'ai essayé avec grails 2.0.4 (avec la console de grails) et cela ne fonctionne pas, il jette une erreur dans une phase où A.contraints n'a pas la propriété de délégué – jneira

1

Fondamentalement, je ne vois pas comment ça peut être fait. De même, une classe de domaine mappe la structure de la table de base de données. Les contraintes généreront réellement des contraintes de DB. Vous essayez donc de créer plusieurs objets qui généreront des contraintes différentes sur la même table. Je pense que la meilleure approche serait de créer un objet de domaine qui a le plus simple sous-ensemble de contraintes, puis d'utiliser différents objets de commande pour affiner les contraintes exactes que vous voulez transmettre au domaine.

Vous pouvez également utiliser le validateur: dans les contraintes pour affiner différentes contraintes pour différents types d'objets (quelque chose comme une colonne types dans le domaine et basé sur différents types fait une validation différente).

-1

Vous devez redéclairer les contraintes de la super-classe car c'est un clojure statique (les propriétés statiques et les méthodes statiques ne sont pas héritées par les classes enfants), donc, ce n'est pas mappé par GORM.

Cheers.

Questions connexes