Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 937
Nathan H Avatar asked May 05 '10 17:05

Nathan H


2 Answers

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 = {
         }
    }
like image 53
Ray Tayek Avatar answered Sep 20 '22 00:09

Ray Tayek


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.

like image 20
Sev Avatar answered Sep 21 '22 00:09

Sev