问题
I need to create a many-to-many relationship in Grails.
I have a "Question" domain and a "Tag" domain. A Question can have 0 or more tags. A Tag can have 0 or more Questions.
If I put a "hasMany" on each sides, it gives me an error saying I need a "belongTo" somewhere. However, adding a belongsTo means that the owner must exist...
Like I said, a Tag could have 0 questions, and a Question could have 0 tags. There is no concept of an owner, it's a many-to-many!
What am I supposed to do?
回答1:
you can do this (please see the code below). but does it make sense to have a question tag with out both a question and a tag?
package m2msansbt
class Question {
String toString() { return name }
String name
static hasMany=[questionTags:QuestionTag]
static constraints = {
}
}
package m2msansbt
class Tag {
String toString() { return name }
String name
static hasMany=[questionTags:QuestionTag]
static constraints = {
}
}
package m2msansbt
class QuestionTag {
Question question
Tag tag
static QuestionTag link(Question question,Tag tag) {
QuestionTag questionTag=QuestionTag.findByQuestionAndTag(question,tag)
if (!questionTag) {
questionTag = new QuestionTag()
question?.addToQuestionTags(questionTag)
tag?.addToQuestionTags(questionTag)
questionTag.save()
}
return questionTag
}
static void unlink(Question question,Tag tag) {
QuestionTag questionTag=QuestionTag.findByQuestionAndTag(question,tag)
if (questionTag) {
question?.removeFromQuestionTags(questionTag)
tag?.removeFromQuestionTags(questionTag)
questionTag.delete()
}
}
static constraints = {
}
}
import m2msansbt.*
class BootStrap {
def init = { servletContext ->
Question q1=new Question(name:'q1')
Tag t1=new Tag(name:'t1')
Tag t2=new Tag(name:'t2')
q1.save()
t1.save()
t2.save()
QuestionTag q1t1=QuestionTag.link(q1,t1)
q1t1.save()
QuestionTag q1t2=QuestionTag.link(q1,t2)
q1t2.save()
q1.save()
t1.save()
}
def destroy = {
}
}
回答2:
If your main concern is the cascading delete, you can take a look at 5.5.2.9 in the grails docs to manually disable it for the mapping.
回答3:
I haven't tried it, but I think the mappedBy property can be used to solve this.
回答4:
Checkout the Taggable Plugin.
It seems to solve the problem you are having and you could look at the source code if you want to see how they modeled the relationship. BTW this plugin was originally created by Graeme Rocher who is the lead developer on Grails.
回答5:
This works for me on Grails 2.4.4. Add a "belongsTo" with just the classname.
class Question {
String toString() { return name }
String name
static hasMany=[tags:Tag]
static constraints = {
}
}
class Tag {
String toString() { return name }
String name
static hasMany=[questions:Question]
static belongsTo = Question
static constraints = {
}
}
来源:https://stackoverflow.com/questions/2775332/how-to-handle-many-to-many-in-grails-without-belongsto