如何在没有belongsTo的情况下处理Grails中的多对多?

时间:2010-05-05 17:13:51

标签: grails many-to-many

我需要在Grails中创建多对多关系。

我有一个“问题”域和一个“标记”域。 一个问题可以有0个或更多标签。标签可以包含0个或更多问题。

如果我在每一侧放置“hasMany”,它会给我一个错误,说我需要一个“belongsTo”。 但是,添加belongsTo意味着所有者必须存在...

就像我说的,一个标签可以有0个问题,一个问题可以有0个标签。 没有所有者的概念,这是多对多的!

我应该做什么?

5 个答案:

答案 0 :(得分:6)

你可以这样做(请参阅下面的代码)。但是有一个带有问题和标签的问号标签是否有意义?

    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 = {
         }
    }

答案 1 :(得分:2)

如果主要关注的是级联删除,您可以查看grails文档中的5.5.2.9,手动将其禁用以进行映射。

答案 2 :(得分:0)

我没有尝试过,但我认为mappedBy属性可以用来解决这个问题。

答案 3 :(得分:0)

结帐Taggable Plugin

似乎可以解决您遇到的问题,如果您想了解他们如何建立关系,您可以查看source code。 BTW这个插件最初是由Grails的首席开发人员Graeme Rocher创建的。

答案 4 :(得分:0)

这适用于Grails 2.4.4。添加一个只有classname的“belongsTo”。

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 = {
    }
}