2011-10-07 1 views
6

Je suis en train de concevoir un système dans lequel les messages/discussions entre utilisateurs peuvent être mis à jour pour devenir des tickets. À un endroit particulier, j'essaie de créer une relation optionnelle en tête-à-tête, mais je rencontre certaines difficultés. Une version condensée des entités à l'honneur est donnée ci-dessous.Grails/GORM: créer une relation optionnelle one-to-one

Règles:

  1. Un message peut devenir un billet si nécessaire. (facultatif)
  2. Un ticket doit contenir un message. (Obligatoire)

Post.groovy

class Post { 

     String title 
     String description 
     String postedBy 

     Ticket ticket 

     static hasMany = [comments: Comment] 

    static constraints = { 
     title(blank:false) 
     description(blank:false) 
     postedBy(blank:false) 
     ticket (nullable:true,unique:true) 
    } 
} 

Ticket.groovy

class Ticket { 

     String title 
     String description 
     String postedBy 

     Post post 

     static hasMany = [responses: Response] 

     static constraints = { 
       title(blank:false) 
       description(blank:false) 
       postedBy(blank:false) 
       post (nullable:false,unique:true) 
     } 

} 

Cela fonctionne dans une certaine mesure. Je peux:

  1. Créer un message laissant le billet attribut null Si et quand le poste est mis à niveau pour devenir un billet
  2. je peux définir explicitement l'attribut de billets de la Poste pour pointer vers le ticket parent.

Toutefois, ce mappage n'est pas appliqué au niveau du domaine. Il laisse place à une situation où Ticket1 pointe vers Post1, mais Post1 pointe vers Ticket2 à la place.

J'ai essayé d'utiliser un static hasOne = [post: Post] dans le Ticket classe mais plus tard appris qu'il donne mandat à la présence d'un static belongsTo = [ticket: Ticket] dans le post classe et cela devient une relation obligatoire 1 à 1 qui est pas ce que je suis à la recherche de.

Existe-t-il un moyen d'obtenir ce mappage optionnel 1-to-1 dans ce scénario? Tous les pointeurs seraient très utiles.

+0

S'il vous plaît fermer la question, si elle est répondue à votre satisfaction. Merci! :-) – sbglasius

+0

Cela ne fonctionne pas. Je ne pense pas que 1-1 puisse être créé. Je devrais probablement le fermer comme sans réponse? –

Répondre

3

Vous pourriez envisager de faire un validateur personnalisé comme

class Post { 
    // Other fields 

    Ticket ticket 

    static constraints = { 
    // Other constraints 
    ticket (nullable:true,unique:true, validator: { val, obj -> 
     if(val) { 
     return val.post == obj 
     } 
    }) 
    } 
} 

Ne serait-ce résoudre votre problème?

+0

Salut, merci pour votre solution! Cela fonctionne (avec la petite modification faite) et est meilleur que la situation précédente puisque maintenant il y a une validation à au moins une fin. Cependant, maintenant il est toujours possible que je mets l'argument de ticket correct dans Post (puisque le validateur l'applique), mais retournons ensuite à Ticket et changeons l'objet Post vers lequel il pointe. Je me demandais simplement s'il y avait un moyen de l'appliquer des deux côtés, mais je suppose qu'il n'y en a pas? :( –

+0

Que diriez-vous d'une autre validation dans l'autre extrémité? Il devrait être possible? – sbglasius

+0

L'essayer maintenant –

Questions connexes