GORM 在 hasMany 关系中直接访问实例

GORM direct access to instance in a hasMany relationship

我有两个域 类 CGroup 和 Directory,我想建模一个有很多目录的 CGroup,但是这些目录中的一个被称为 "root",并且可以直接访问来自 C 组。任何 CGroup 都应该只有一个根。级联应该仍然有效,这样删除任何目录都会删除其所有子目录。

虽然错了,但这是我目前的情况:

class CGroup{
    ...
    Directory root

    static hasMany = [directory:Directory]

    static constraints = {
        root(unique:true)
    }
}

class Directory {

    static hasMany = [children:Directory]
    ...
    static belongsTo = [parent:Directory,
                        cgroup:CGroup]

    static constraints = {
        parent nullable: true
    }
}

基本上,我只需要引用 "many" 集合中的一个实例,存储在 "one" 端

我尝试了几种不同的方法,唯一能让它工作的方法是允许 root 暂时可为空。没有这个我遇到的问题是由于排序 - 因为 Directory 实例在 hasMany 中,所以在保存 CGroup 之前它们无法保存,否则 save() 调用将失败,因为cgroup 为空(这是在调用 addToDirectory 时设置的)。但是,如果 CGroup 不可为空,则不能在不设置其 root 属性 的情况下保存 CGroup。

所以我让 root 可以为 null 但添加了一个自定义验证器,如果 root 为 null 并且 hasMany:

中有任何实例则验证失败
static constraints = {
   root nullable: true, validator: { Directory root, CGroup cgroup ->
      if (!root && cgroup.directory?.size()) {
         return ['root.required']
      }
   }
}

因此,您将使用任何必需的值保存 CGroup 实例,而没有任何关联的 Directory 实例。然后将 Directory 实例附加到 addToDirectory 并使用自定义 setter:

设置 root 实例
void setRoot(Directory root) {
   if (this.root) {
      removeFromDirectory this.root
   }

   if (root) {
      addToDirectory root
   }

   this.root = root
}

并再次保存:

def group = new CGroup(...).save()

group.root = new Directory(...)
group.addToDirectory(new Directory(...))
group.addToDirectory(new Directory(...))
group.save()

g1.errors