Last time, we created the domain-class User. Meanwhile I found this name a bit ambiguous, so I renamed it to
Employee. In addition to Employee, I need some other domain-objects to support my application. I need a Company, Department, Customer, Project, ProjectExpense, ProjectWorkUnit. And of course these are related in some way or another, leveraging the powers of GORM.
First off, let´s create the domain-classes using the grails interactive mode
// start interactive mode by typing "grails"
# create-domain-class worklog.Employee
# create-domain-class worklog.Company
# create-domain-class worklog.Department
# create-domain-class worklog.Customer
# create-domain-class worklog.Project
# create-domain-class worklog.ProjectExpense
# create-domain-class worklog.ProjectWorkUnit
# create-domain-class worklog.ProjectRole
Now, a company can have several departments. To tell GORM about this relation, I simply use the "hasMany" property in Company, along with some other sane constraints:
package worklog
class Company {
String domain
String name
Date dateCreated
static hasMany = [ department:Department]
/**
* hibernate plugin event-method
* @return
*/
def beforeInsert(){
dateCreated = new Date()
}
static constraints = {
domain(unique: true)
name(nullable: false)
}
String toString(){
domain
}
}
By default all properties are non-nullable in GORM, but I like to specify non-nullable constraints I think are important for my domain-class. The "hasMany" keyword tells GORM that Company can have 0 or more departments. The domain-property is unique for each Company, so I added the unique-constraint. Before inserting a new Company into the database, the beforeInsert() method is run by GORM, so I grab the opportunity to put a createdDate on the object.
It´s possible(and necessary) to have several relations declared in the hasMany property. For example, a project can have related both roles, expenses and work-units:
class Project{
...
static hasMany = [projectRoles: ProjectRole, projectWorkUnits:ProjectWorkUnit, projectExpenses:ProjectExpense]
...
}
Also, an employee has to know to wich department he/she belongs to, expressed by the belongsTo keyword.
...
class Employee{
static belongsTo = [department:Department]
}
...
Now, my total domain model is mapped and since I use intellij, a nice drawing of my relations are illustrated like this:
With a nice domain-model in place, I need some test-data to test my app locally. In my Bootstrap.groovy-file there is an init-method. This will be run every time the application starts, so we can add some test-data here. Grails has built-in methods to check for what environment we are in so we don´t create test-data in our production environment.
class BootStrap {
def init = { servletContext ->
switch (Environment.current) {
case Environment.DEVELOPMENT:
Company webstep = new Company(name: "webster", domain: "webstep.no").save()
Department oslo = new Department(company: webstep, name: "Konnsulting", city: "Oshlo").save()
Employee nils = new Employee(department: oslo, email: "nilsmagnus@gmail.com", securityRole: SecurityRole.NORMAL).save()
Customer icu = new Customer(name: "icu").save()
Project icuRefactoring = new Project(department: oslo, customer: icu, name: "refactoring legacy code").save()
ProjectRole developer = new ProjectRole(employee: nils, project: icuRefactoring, hourRate: 1200.0, description: "Develop some cool shait").save()
ProjectExpense calculatorPurchase = new ProjectExpense(description: "new calculator", project: icuRefactoring, projectRole: developer, amount: 1300.0 ).save()
break
}
}
}
This fills in some data for testing purposes, now we just need to see the data in our app. To get started with ui, I think it´s nice to generate html and controllers with grails using the built in "generate-all" command. For each domain-class I enter the command
# generate-all worklog.Employee
....
# run-app
And its time for inspection :)
To recap: GORM takes care of database-mapping and intellij shows you the relations in your app. Easy as that.
Next time: some testing. Later on I will be doing the gorm critierias to create nice reports.