Reputation: 1121
Is there a way to create an association to an arbitrary domain object in grails?
Something like
class ThingHolder {
DomainObject thing;
}
and then
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()
So that
ThingHolder.get(t1.id).thing // will be a Book
and
ThingHolder.get(t2.id).thing // will be an Author.
Upvotes: 0
Views: 83
Reputation: 1121
I'm still looking for a grailsier way to do this, but this seems to get the job done.
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);
}
}
Assuming you have a Book and Author (that do not override the ID attribute for the domain object).
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 }
I found some extremely useful tips in these two answers.
How to make binding work in default constructor with transient values.
How to generate a domain object by string representation of class name
Upvotes: 1
Reputation: 24776
UPDATE (based on comment)
Since you don't want to (or can't) extend another class in your domain model, this won't be possible using GORM.
ORIGINAL Answer
Yes, you can do this. It's called inheritance. In your case you would have a Thing
which is the super class of both Author
and Book
.
Your domain model might look like this:
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
}
Since both Author
and Book
extend Thing
they are considered to be a Thing
as well.
However, doing this without understanding inheritance and how Grails/GORM models the data in your database is short sighted. You should research those topics fully to make sure this is really what you want.
Upvotes: 0