Domain object modeling with Groovy enums

Overview

I recently had a need to use enumerated values within a Grails domain object model.   After doing some searching on the web, it looked like Grails 1.1 would properly support enumerations, but I was unable to find any documentation showing an example of this.  I was able to figure it out, but I thought it would be helpful to others if I wrote it up in a wiki entry.  My object model in question consists of a single type, the User type.  I want a UserRole enumeration type associated with this User type, but I don't want to have to map it to a table in the database as if it's an entity.  I want GORM to properly handle the mapping of the UserRole enumeration type within the User type.  I also want GORM to output friendly enumeration names for database values instead of ordinal values.


Solution

First, I created the following Groovy enumeration in the domain folder of my Grails application:
 1 public enum UserRole {
2 SYSTEMS_ADMINISTRATOR('Systems administrator'),
3 PROJECT_OWNER('Project owner'),
4 PROJECT_MEMBER('Project member')
5
6
String name
7
8
UserRole(String name) {
9 this.name = name
10 }
11
12 }
The enum will get a static values() method by default that will return the list of enumeration values in the order that they are declared in the enum (thanks to Burt Beckwith for this information).  
 
I then used this UserRole enumeration type within my existing User domain class:
 1 class User {
2
3
String firstName
4 String lastName
5 String username
6 String password
7 Boolean active = Boolean.FALSE
8 UserRole userRole
9
10
// Automatically updated by GORM
11 Date dateCreated
12
13
// Automatically updated by GORM
14 Date lastUpdated
15
16
static constraints = {
17 firstName(blank: false)
18 lastName(blank: false)
19 username(blank: false, unique: true)
20 password(blank: false)
21 active(nullable: false)
22 userRole(nullable: false)
23 }
24
25 }
26

GORM will automatically map the UserRole value in the User class to the user_role database column in the user table.  Therefore, if I used UserRole.SYSTEM_ADMINISTRATOR in my User instance, subsequently saving the User instance and inspecting the database I would see "SYSTEM_ADMINISTRATOR" in the user.user_role column of the corresponding row in the database.  I like this default approach, as the values are easily discerned by anyone looking at the database (as opposed to ordinal values of 1, 2, or 3).  

I can now update my edit and create GSPs to handle this new UserRole, displaying the friendly names for each UserRole value (the optionValue attribute allows the name attribute of the UserRole enumeration to be displayed in the SELECT):
 1               <g:select name="userRole" id="userRole"
2 from="${UserRole.values()}"
3 value="${fieldValue(bean: userInstance, field: 'userRole')}"
4 optionValue="name"/>
5

I did not have to do anything special to my UserController to handle the new UserRole property on the User.  Ah, the beauty of Grails and GORM.



Comments