Creating controllers to enable scaffolding
A controller is used to handle all web requests related to a given domain class. For example, the UserController
class will handle all default actions for the User
domain class (create, edit, list, delete and so on). Once a controller is created, there is no configuration needed to make it accessible to users. All the actions that are declared on the controller are available through a URL based on the controller and action name. The base URL for UserController
is http://localhost:8080/teamwork/user
. The action that allows a user to be created is accessible through the URL, http://localhost:8080/teamwork/user/create
.
It is time to get Grails to create a readymade application by generating scaffolding for the User
and the Role
domain classes. Scaffolding is made available through a controller for each domain class. To create the controllers, go back to your command line and run:
>grails create-controller app.User >grails create-controller app.Role
This will create two controller classes in the app
package under the grails-app/controllers/app
directory.
The new UserController
class will contain the following code:
package app class UserController { def index = { } }
While the RoleController
will contain:
package app class RoleController { def index = { } }
In UserController.groovy
remove the line def index = {}
and add the scaffold
property to enable scaffolding for the User
domain class.
package app
class UserController {
def scaffold = User
}
The highlighted line in the code above creates a publicly available scaffold
property on instances of the UserController
class. The def keyword declares a variable of dynamic type, while the assignment of User
is giving the scaffold property the value of the User
class. The equivalent Java code would look something like this:
private Object scaffold = User.class public void setScaffold( Object scaffold ) { this.scaffold = scaffold; } public Object getScaffold() { return this.scaffold; }
Member variables without a scope definition are also published as public
properties in Groovy. This is covered in more detail in Chapter 4.
Now, in the RoleController.groovy
file, remove def index = {}
and add the scaffold
property to the controller to enable scaffolding for the Role
domain class.
package app
class RoleController {
def scaffold = Role
}
Now, restart the application from your command line and go to the home page at http://localhost:8080/teamwork
. You will be greeted by the default home page, as before, but this time there will be two new links:
- app.RoleController
- app.UserController
By clicking on the app.UserController link, you will see that you now have a basic set of screens for listing, viewing, creating, editing, and deleting users.
The list page shows a table of users, which is of course empty at the moment, with headings for some of the properties of a user. Let's take a moment to consider the elements of the page and examine how the Grails scaffolding has managed to create them from our User domain
class. The following elements are dynamically generated:
- The page title (User List)
- The navigation (New User link)
- The table title (User List)
- The table headers
The page title, navigation, and table title are all generated from the name of the domain class. The table column headings come from converting the property names into readable text by assuming that your properties will be in camel case and using the capital letters to denote word breaks. So, the firstName
property is displayed as First Name.
At this point, you might be wondering where the Id column has come from, as you did not give the User
domain class an id
property. Each domain class has a dynamic property called id
added to it at run time by Grails. This is the database identifier of the object that is assigned when instances of the class are saved to the database.
If you click on the New User link in the navigation on the list page, you will be taken to the Create User page as shown in the following screenshot:
The Create User page uses the same conventions as the User List page for displaying the page title, navigation, form heading, and property names. In addition, the scaffolding will render an input field based on the data type of the property. You can see that the input fields for the dateCreated
and lastModified
properties have been rendered differently because they are Date
objects rather then String
objects.
Grails applications will startup with an in-memory HSQLDB database by default. If you fill in the fields on the Create User page and click on the Create button at the bottom of the form a new user will be saved in the database. You can verify this behavior by going back to the User List page; you should see the details of the new user displayed as a row in this table.
Just as controllers are able to handle web requests by virtue of existing in the controllers
folder, domain classes can be persisted to the database without any need for configuration. This allows the scaffolding code to persist the data entered by the user to the database without requiring any additional information from us.