Grails关系涉及多个表,可能是多对多

Grails关系涉及多个表,可能是多对多,grails,gorm,relationship,tag-cloud,Grails,Gorm,Relationship,Tag Cloud,问题在于将事件实例链接到标记实例。保存时现在已实现的事件…但仍存在设计问题,因为一个标记可能与多个事件相关,一个事件可能有0到多个标记 在标准的save()方法中,我在方法tagInput()中调用,该方法从表单tagscolection字段(请参见屏幕截图)中获取字符串,该字段分隔单词并创建/保存标记的实例(请参见下面的方法)。每个单独的值都链接到登录的用户,现在链接到事件 总体问题是如何向创建的每个标记添加多个事件实例id,以便标记数据库中的事件id不会被使用相同标记名的较新事件覆盖 &&

问题在于将
事件实例
链接到
标记实例
保存时现在已实现的事件…但仍存在设计问题,因为一个标记可能与多个事件相关,一个事件可能有0到多个标记

在标准的
save()
方法中,我在方法
tagInput()
中调用,该方法从表单
tagscolection字段
(请参见屏幕截图)中获取字符串,该字段分隔单词并创建/保存
标记的实例(请参见下面的方法)。每个单独的值都链接到登录的用户,现在链接到事件

总体问题是如何向创建的每个标记添加多个事件实例id,以便标记数据库中的事件id不会被使用相同标记名的较新事件覆盖

&&

用户类(与Grails安全插件一起使用)

标记类(用于标记云Grails插件)

事件类

String tagsCollection
User user
static hasMany = [tags: Tag]

因此,现在一个事件id正在保存到一个标记实例,但是对于同一个用户重复使用同一个标记是有问题的,因为它需要具有多个相关事件id的搜索能力

def tagInput(Event e) {
    //Stores tags sperated via comma in an array from the eventInstance tagCollection string field
    def tagArray = e.tagsCollection.replaceAll("\\s+","").toLowerCase().split(",")

    tagArray.each { aVar ->
        def splitTag = Tag.findByTag(aVar)
        //If the tag already exists for the current user logged in
        if (Tag.findByTag(aVar) && splitTag.userId == lookupPerson().id) {
        //Lookup person spring security method
        //+1 to how many times that tag has been used
            splitTag.times++

            //TODO IMPLEMENT A WAY TO APPEND EVENT ID TO TAG EVENT_ID FIELD

            splitTag.save(flush: true, failOnError: true)
        }  else {
            //if tag doesn't exist, create a new one using current logged in user
            def nTag = new Tag(tag:aVar, times: 1, user:lookupPerson())
           //SUGGESTION to save event id to a tag
            e.addToTags(nTag)
            e.save()
            //Set a user to own this tag
            def u = User.find(lookupPerson())
            nTag.save(flush: true, failOnError: true)
            u.addToTags(nTag)
            u.save()
        }
    }
}

(为了测试,我使用了一个用户,第一个事件创建了5个标记,请参见数据库屏幕截图,然后使用同一个用户创建了第二个事件,并使用了上一个事件t1和t5中先前创建的两个标记)

我如何向创建的每个标记添加事件实例id,当尚未创建id时…

你不能,你也不需要这样做。按定义标记实例不需要事件实例引用,因为域类中不包含事件属性

因此,您可以创建标记实例并保存它,而不保留事件实例:只需从
tagInput()
方法返回保存的标记实例列表。在save()方法中,保存eventInstance后,将标记列表添加到其中,如下所示:

tagInstancesList.each{tagInstance->
    eventInstance.addToTags(tagInstance)
}

[因此,您正在创建一个事件,您可能需要创建新的标记

因此,为了保存并级联到标记,必须在标记类上定义一个belongTo:

class Tag {
...
static belongsTo = [Event, User]
}
现在你可以说:

Event event = new Event(...)
event.addToTags( new tag(...) )
event.save()
也应该保存您的新标记


编辑:您的
新标记
可能类似于
标记。findOrCreateByUserAndTag(用户,名称)
。如果标签已经存在,这将找到它,如果它不存在,它将创建它。显然,将用户和名称变量替换为您正在使用的变量。

这部分是不正确的。标签不需要事件,但是您可以启用层叠保存。在这种情况下启用层叠有什么好处?我不明白。因此,您不必单独验证对象,这与OP无关。感谢@JamesKleeh和@Jinzhao Wu两位的回复……但是,这个问题并没有为我解决,直到愚蠢地解决了这个问题,我才意识到我的问题:/。它现在正在将
事件实例id
保存到标记中,这要感谢你们两位:)……但是,一个例子use案例:用户创建另一个事件并希望使用相同的标记,是否有方法将多个id添加到以下标记中?我将使用
tagInput()更新我的代码
谢谢你的回复,我在你的帮助和@kinzhao Wu的帮助下成功地做到了这一点,我将
下的
更改为
事件的
,就像你对
事件所说的那样,所以当我在
保存()
中调用
tagInput(eventInstance)
时,我添加了
eventInstance.addToTags(Tag Instance)
然后
eventInstance.save()
我认为问题在于我看错了设计……它必须是多对多的,即标记有多个事件,事件有多个标记……关于处理多对多关系有什么提示或提示吗?我对如何导航这方面的工作没有信心……我认为grails文档不是最好的。谢谢
class Tag {
...
static belongsTo = [Event, User]
}
Event event = new Event(...)
event.addToTags( new tag(...) )