有没有办法在grails中创建与任意域对象的关系

Is there a way to create a relationship to an arbitraray domain object in grails

有没有办法在 grails 中创建与任意域对象的关联?

类似

class ThingHolder {
    DomainObject thing;
}

然后

Book b=new Book(title: "Grails 101").save()
Author a=new Author(name: "Abe").save()

ThingHolder t1=new ThingHolder(thing:b).save()
ThingHolder t2=new ThingHolder(thing: a).save()

所以

ThingHolder.get(t1.id).thing  // will be a Book

ThingHolder.get(t2.id).thing  // will be an Author.

更新(基于评论)

由于您不想(或不能)在您的域模型中扩展另一个 class,因此使用 GORM 是不可能的。

原始答案

是的,你可以做到。这叫做继承。在您的情况下,您将有一个 Thing,它是 AuthorBook 的超级 class。

您的域模型可能如下所示:

class Thing {
  // anything that is common among things should be here
}

class Author extends Thing {
  // anything that is specific about an author should be here
}

class Book extends Thing {
  // anything that is specific about a book should be here
}

class ThingHolder {
  Thing thing
}

由于 AuthorBook 都扩展了 Thing,因此它们也被认为是 Thing

但是,在不了解继承以及 Grails/GORM 如何对数据库中的数据建模的情况下这样做是短视的。您应该充分研究这些主题,以确保这确实是您想要的。

我仍在寻找更简单的方法来执行此操作,但这似乎可以完成工作。

class ThingHolder {
    static constraints = {
        thing bindable:true // required so 'thing' is bindable in default map constructor.
    }

    def grailsApplication;

    Object thing;

    String thingType;
    String thingId;

    void setThing(Object thing) {    //TODO: change Object to an interface
        this.thing=thing;
        this.thingType=thing.getClass().name
        this.thingId=thing.id;       //TODO: Grailsy way to get the id
    }

    def afterLoad() {
        def clazz=grailsApplication.getDomainClass(thingType).clazz
        thing=clazz.get(thingId);
    }
}

假设您有书籍和作者(不会覆盖域对象的 ID 属性)。

def thing1=new Author(name : "author").save(failOnError:true);
def thing2=new Book(title: "Some book").save(failOnError:true);

new ThingHolder(thing:thing1).save(failOnError:true)
new ThingHolder(thing:thing2).save(failOnError:true)

ThingHolder.list()*.thing.each { println it.thing }

我在这两个答案中发现了一些非常有用的提示。

How to make binding work in default constructor with transient values.

How to generate a domain object by string representation of class name