I have two domain classes, Person and Workshop. A Workshop has an owner of type Person, and many participants of type Person. A Person can be the participant of many workshops. When enrolling people in workshops I want to do so from the Workshop side like workshop.AddToParticipants() so here is how I set up my domain classes.
class Person {
String name
static hasMany = [enrolledWorkshops: Workshop]
static belongsTo = [Workshop]
}
class Workshop {
Date startDate
Date endDate
String name
Person owner
static hasMany = [participants: Person]
}
GORM correctly creates a WORKSHOP_PARTICIPANTS table with WORKSHOP_ID and PERSON_ID columns, and adds an OWNER_ID column to the WORKSHOP table. This is all good.
However, it ALSO creates a WORKSHOP_OWNER table with PERSON_ID and OWNER_ID columns! This makes no sense to me, and no matter how I try changing the GORM relationships I just can't get it to work how I want without this annoying extra table being created. How can I prevent the WORKSHOP_OWNER table from being created? Any help is greatly appreciated! (if it is of any help, I am using Grails 2.3.7)
In order to get rid of the WORKSHOP_OWNER table you'd have to replace Person owner
with static belongsTo = [owner: Person]
in the Workshop class. But that would conflict with static belongsTo = [Workshop]
in the Person class. Both can't be owners.
Try this:
class Person {
String name
}
class Workshop {
Date startDate
Date endDate
String name
static belongsTo = [owner: Person]
static hasMany = [participants: Participant]
}
class Participant {
person person
static belongsTo = [workshop: Workshop]
}
In the above example, a Person
owns a Workshop
, and a Participant
is owned by a Workshop
. The workshop table will get a owner_id to refer to the person, which gets rid of the workshop_owner table.
To add a Person
to a Workshop
you simply wrap it in a Participant
workshop.addToParticipants(new Participant(person: somePerson))
You'd loose the enrolledWorkshops property in Person
, but you can accomplish the same thing with a query.
def workshops = Workshop.withCriteria {
participants {
eq 'person', somePerson
}
}