How to handle Many-To-Many In Grails without belongsTo?

故事扮演 提交于 2019-12-08 17:43:53

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!