Defining the relationship
What you're defining is a unidirectional one-to-many, with the parent being the 'owner' of the relationship. If you define it like this:
class RoleType {
String roleName
String description
static hasMany = [children: RoleType]
}
Then you can do something like this:
def superManager = new RoleType(roleName: 'SuperManager')
def manager = new RoleType(roleName: 'Manager')
superManager.addToChildren(manager);
Or I believe you can shorthand the same thing like this:
def superManager = new RoleType(roleName: 'SuperManager').addToChildren(roleName: 'Manager').save()
By defining the relationship with [children: RoleType]
, Grails creates a collection on the domain called children
that you can access like any other property, e.g. myRole.children.each { it.doSomething() }
.
To make it easier to work with, you could also make the relationship bidirectional by adding the following property:
RoleType parent
If you use the dynamic addTo*
methods, they should ensure that both ends of the relationship get their properties correctly set. Have a look at this for additional reference.
Retrieving all descendants
You have a few options here, but I don't think there's a way built into GORM to do it automatically.
One option would be to write your own recursive or iterative method that grabs and collects all of the children. An example of this can be found here.
Alternatively, if you execute this method a lot and it become a bottleneck, you could do some manual manipulation of your database. You might have triggers that operate on inserts and updates in your RoleType table that maintain lists of implicit relationships between all RoleTypes.
For example, if you create a RoleType A
-> RoleType B
-> RoleType C
relationship, the triggers might create (in a separate table) a RoleType A
-> RoleType B
, RoleType A
-> RoleType C
, and RoleType B
-> RoleType C
relationship. You could then query this table by a single parent and get all of its implied children/descendants. I've seen this done for complex ACL processing.