Domain outlay:
class User {
String username
static hasMany = [userRoles: UserRole]
}
class Role {
String authority
}
class UserRole {
User user
Role role
static belongsTo = [User, Role]
}
That is a condensed version of what you’ll normally find when you install the grails spring-security-core plugin.
Now, a user can have more than one role. Thus, an admin can be a normal user. User:UserRole = 1:M
In SQL it would be easy to get a set of users where there isn’t a user role attached to it.
How does one do it with the Grails criteria builder?
As a stop gap fix (until I get a nice answer that is not basically plugging SQL into Grails), I basically get all the admin users as a set, then I get the list of users as another, and one for one remove all the admin user out. Ugly, but it works (slowly):
def existing = UserRole.createCriteria().listDistinct {
eq("role",adminRole)
}.collect{it.user} as Set
def f = User.createCriteria().listDistinct {
userRoles {
ne("role",adminRole)
}
}.collect{it} as Set
existing.each { ex ->
f.each { non ->
if (non.id == ex.id) {
f.remove(non)
}
}
}
In the code above, if you do f.removeAll(existing) it doesn’t work.
I think this would be a nice question to answer as you can apply the same to other scenarios as well.
Thanks in advance!
I’m not sure how to do it with a criteria query, but this HQL works: