Thursday 9 February 2012

Converting param values in Grails

There are some cases in Grails where you want to compare values as Integers instead of the default String objects. There are two ways to do this. The first is to use either the "parseInt" or "valueOf" methods which are original Java methods. The other way to skin this cat is to call the "int()" method on the params object:

if(Integer.parseInt(params.user.id) != user.id){
...
}
if(params.int('user.id') != user.id){
...
}


There are other methods which the params object has to easily convert HTTP post values to well known data types, such as:

param.short(...)
param.byte(...)
param.long(...)
param.double(...)
param.boolean(...)


Another nice feature is that these methods accept a second optional parameter, which is the default that the value is set to, in the case that there is an error in the conversion:

def price = prams.float("seventy", 0.0)

This behaviour is documented in the Grails documentation here. Although, there doesn't seem to be a comprehensive list of the methods available at the time of writing.

STS/Eclipse version control plugins

STS/Eclipse has a number of plugins which make it easy to work with your version control system right in your IDE. Which one you install largely depends on which version control system you're working with.

If you're working with Subversion, you'll want to use the Subversive plugin. There is also a Subclipse plugin which apparently does the same thing, but I haven't had time to try it out as I've been quite happy with Subversive and if it's not broken...

If you're working with Git, you'll want to use the EGit plugin. I've used this plugin to hook up my projects with GitHub and haven't had any major dramas with it so far.

Wednesday 8 February 2012

Grails - Setting failOnError globally

One of the small annoyances with Grails that I've found is that the application doesn't fail when a call to the "save" method fails. One of the ways to fix this is to pass the "failOnError" parameter to the save method, set to true:

def book = new Book(title: "The Shining").save(failOnError: true)

However, this gets annoying, having to pass the parameter every time that you call the "save" method. A solution is to declare it as the default setting and forget about it.

This can be done in Config.groovy, by adding the following line:

grails.gorm.failOnError=true

You can also add this configuration to specific packages, in case that you didn't want the configuration to apply to all of the packages used in your application:

grails.gorm.failOnError = ['com.companyname.somepackage','com.companyname.someotherpackage']

From: http://grails.org/doc/latest/guide/conf.html#configGORM

Tuesday 7 February 2012

Override the toString method in Grails

The Grails framework is pretty smart in that if you have objects that are related to another object, it will allow you to associate an object at creation time. For example, if you had an User class, which had a "hasMany" relationship with the Post class, when creating a new Post object you would see a drop down allowing you to select a User:


Note that this is assuming that you've used the "generate-all" command to create the default scaffolding. The screen listing the Posts also shows the User:



However, as we can see from the above screenshot the values in the drop down and the User field don't seem to make much sense. The reason for the values are that by default the scaffolding generator calls the "toString" method on the object. Which is set to return the class name of the object, plus it's unique id. While this makes sense to have as the default, we need to change it in order to make it easier for people to read.

Fortunately, changing it is quite straightforward, with us only needing to define (override) the toString method. Simply add the following to the User domain class:

String toString(){
  return username
}


After putting this into the User controller, restart the grails application and you should see the usernames of the users in the drop down when creating a new Post:


This works for any class that you can think of. Simply override the toString method to make it more presentable to the people using the site. I do this almost automatically for all of my domain classes.