blob: 8814982f057be11e5a6632d7c3dd184f8611bb22 [file]
[[personAuthorityClass]]
=== PersonAuthority Class
The typical approach to mapping the relationship between "`person`" and "`authority`" is a many-to-many. Users have multiple roles, and roles are shared by multiple users. This approach can be problematic in Grails, because a popular role, for example, `ROLE_USER`, will be granted to many users in your application. GORM uses collections to manage adding and removing related instances and maps many-to-many relationships bidirectionally. Granting a role to a user requires loading all existing users who have that role because the collection is a `Set`. So even though no uniqueness concerns may exist, Hibernate loads them all to enforce uniqueness. The recommended approach in the plugin is to map a domain class to the join table that manages the many-to-many, and using that to grant and revoke roles to users.
Like the other domain classes, this class is generated for you, so you don't need to deal with the details of mapping it. Assuming you choose `com.mycompany.myapp` as your package, and `User` and `Role` as your class names, you'll generate this class:
[source, groovy]
.`UserRole.groovy`
----
include::../code/s2-quickstart/grails-app/domain/com/mycompany/myapp/UserRole.groovy[]
----
The helper methods make it easy to grant or revoke roles. Assuming you have already loaded a user and a role, you grant the role to the user as follows:
[source,groovy]
.Listing {counter:listing}. Granting a role
----
User user = ...
Role role = ...
UserRole.create user, role
----
Revoking a role is similar:
[source,groovy]
.Listing {counter:listing}. Revoking a role
----
User user = ...
Role role = ...
UserRole.remove user, role
----
The class name is the only configurable attribute:
.UserRole configuration options
[cols="30,30,40"]
|====================
| *Property* | *Default Value* | *Meaning*
|userLookup.authorityJoinClassName
|_none_
|User/Role many-many join class name
|====================