Controllers and views round out the “Big Three” in Grails applications. The Model/View/Controller (MVC) pattern is undoubtedly familiar to most web developers. By enforcing a clean separation of concerns among these three elements, your efforts are paid back in terms of maximum flexibility and reuse.
Grails supports both static and dynamic scaffolding. The First example will show how to work with the static scaffolding. And afterwards there will be a small example on how to use dynamic scaffolding
Static Scaffolding
To generate the scaffolds in Grails, the following command will need to be executed through the command-line inside the project directory
In this example, the ‘Address’ domain class will be scaffolded. The Controller and Views will now be generated for the developer. The way the code is generated, is based on templates that can be changed.
Next to the CRUD actions, Grails adds the “list” action. The “edit” and “save” functions work together with “update” and “create”.
Create | create.gsp | Creates a new address |
Read | show.gsp | Show one address (Based on ID) |
Update | edit.gsp | Retrieve one address (Based on ID) that needs to be changed |
Delete | No view | Delete one address (Based on ID) |
List | list.gsp | List all addresses |
Edit | No view | Save the updated address |
Save | No view | Saves the newly created address |
The AddressController now looks like this. The functions are self-explanatory.
Class AddressController { Def index = { redirect (action:list, param:param)} //delete , save and update actions only accept post requests def allowedMethods =[delete: ‘POST’ , save:’POST’ , update: ‘POST’] def list = {//…….} def show = {//…….} def delete = {//…….} def edit = {//…….} def update = {//…….} def create = {//…….} def save = {//…….}
Dynamic Scaffolding
Dynamic Scaffolding in Grails is really easy. This can be achieved by adding the following line inside the controller that needs to be scaffolded.
def scaffold =true
The CRUD actions and views will be automatically generated at runtime for the previously defined model
Domain Classes
Domain classes are the lifeblood of a Grails application. A corresponding database table is automatically created for each domain class. Controllers and views derive their names from the associated domain class. This is where validation rules are stored, one-to-many relationships are defined, and much more.
Below command to create domain class
grails create-domain-class domain-class-name
Notice that Grails creates both a domain class and a test class. We’ll put the test class to use later. For now, let’s focus on the domain class
Databases – GORM
The Grails Object-Relational Mapping API allows us to stay squarely in an Object frame of mind – no getting bogged down in relational database-related SQL
GORM is a thin Groovy façade over Hibernate
While creating an application, Grails automatically creates a Data source class where configurations for different environments can be defined. This allows for an easy switch between the development, test and production stage of a project
GORM data source could be configured on grailsapp/conf/DataSource.groovy
dataSource { pooled = true driverClassName = “org.hsqldb.jdbcDriver” username =”sa” password = “” } Hibernate { Cache.use_second_level_cache = true Cache.use_query_cache = “true” Cache.provider_class = ‘com.opensymphony.oscace.hibernate.OSCachePovider’ } Environment { Development { dataSource { // one of ‘create’, create-drop’ , ‘update’ dbCreate= “create-drop” urk = “jdbc:hsqldb:main:devDB” } } Production { dataSource { dbCreate = “update” url = “jdbc:hsqldb:file:prodDB;shutdown=true” } } }
Controllers
View and Controller will be generated based on the Model and will automatically implement CRUD actions.
Here we will expose the default scaffolded Controller code so that and relationship between actions in the Controllers and the URL. It will also allow us to see the relationship between action and the corresponding Groovy Server Pages (GSPs).
create-controller vs. generate-controller
Controller will be generated using scaffolding not only it generate controller but also generate GSP view using def scaffold =true.
Normally I’d have you type “grails create-controller User” at this point. Recall that the create-* commands create an empty, stubbed out class. Instead, type grails generate-all User. The generate-all command writes out a fully implemented controller and a corresponding set of GSP views. (You can also type generate-views to see just the GSPs, or generate-controller to create just the Controller.) Instead of the one-line Controller you are used to seeing, you’ll now see 100 lines of Groovy code
URLs and Controllers
Class UserController { Static allowedMethods = {save: “POST”, update : “POST” , delete: “POST”| def index = { redirect {action: “lisy” , params} } def list = { params.max = Math.mi(params.max ? params.int(‘max’) :10,100) def create = { def userInstance =new User () userInstance.properties = paams return { userInstance : userInstance} def save = {//…….} def show = {//…….} def delete = {//…….} def edit = {//…….} def update = {//…….} }
Consider the types of URLs we saw as we worked our way through the application:
http://localhost:9090/application/user/show/2
Each component of the URL plays an important role in the Grails convention. And it’s by following that convention that we (thankfully) free ourselves from having to wire together our URLs, controllers, and views in external configuration files
The first part of the URL is the application name, or Application Context Root. The next part of the URL is the controller name. Notice that the Controller part of UserController gets dropped off, and the first letter is changed to lowercase. After the controller name, you’ll see an optional action name. This name corresponds directly to the action in the Controller.
If we try “http://localhost:9090/application/user” in our web browser, we will end up with an empty list of users. Since no action is specified, Grails routes the request to the index action. The index action, in turn, redirects the request to the list action, passing along the query string as well. The name:value structure used in the redirect method is used throughout Controllers.