Blog, Software Engineering

Grails cheat sheet

This is a little cheat sheet I created for learning purposes. I’m extending this as I need. Many of the tips are collected from the Getting Started With Grails minibook, which is a great resource for a kickstart.
All stuff after the break… click “Continue” to continue reading.

General

Logging

// A "log" attribute is available in all controllers,
// services and domain classes.
log.debug( "The value of a is ${a}" )
// Everywhere else, use Commons Logging to get hold
// of a logger.
Log log = LogFactory.getLog( YourClass.class )
log.info( "Foo!" )

Build a message using a code and parameters:

flash.message="${message( code: 'the.message.code', args: [ message( code: 'other.message', default: 'ADefaultMessage' ), variable.property ] ) }"

Formatting extension for java.util.Date

new Date().format( "yyyy" )

Check if request is Ajax request
Thanks to Groovy, the HttpServletRequest can be enhanced with a new getter which checks for the X-Requested-With header. Add this to BootStrap.groovy init method.

HttpServletRequest.metaClass.isXhr = {->
	'XMLHttpRequest' == delegate.getHeader( 'X-Requested-With' )
}

Domain Objects

Define transient attributes

static transients = [ 'attr1', 'attr2' ]

Define constraints on attributes
All domain properties have an implicit nullable: false constraint!

static constraints = {
	attr1( blank: false, nullable: false, unique: true, password: false )
}

Find with dynamic finders (Limited to one or two fields!)

def result = DomainObject.findAllByAttr( searchValue )
def result = DomainObject.findAllByAttrAndOther( searchValue1, searchValue2 )

Manage relationships (Documentation)

class Movie {
	String name
	static hasMany = [ actors: Actor ]
	static constraints = { name( nullable: false ) }
}
class Actor {
	String name
	static belongsTo = [ movie: Movie ]
}
// Set<Actor> is automatically created if necessary
def movie = new Movie( name: "The Social Network" )
			.addToActors( new Actor( name: "Jesse Eisenberg" ) )

Controllers

URL mapping – edit file in conf/UrlMappings.groovy

class UrlMappings {
	static mappings = {
		"/$controller/$action?/$id?" {
			constraints {
				// apply constraints here
			}
		}
		"/" ( view: "/index" )
		"500" ( view: "/error" )
	}
}

Four possible scopes (also in GPSs)

page.
flash.value = "stuff";
request.
session.
application

Redirect

redirect( action: "login" )
redirect action: "list", params: params
redirect( controller: "user", action: "login" )

Render a view different to the action name

render( view: "viewName", model: [ name: value ] )

Interception on controller-basis

def beforeInterceptor = [ action: this.&auth, except: [ 'login', 'logout', 'authenticate' ] ]
def auth() {
	// Check that the user is actually logged in
	return true // return false
}

Partial rendering Source)

class MyController {
	def test = {
		def x = g.render( template: "/basecontroller/test", model: [ name: "wysmedia.com" ] ); // stored as string ...
		render( x ); // display the template instead render
	}
}

Filters

Create file conf/AdminFilter.groovy

class AdminFilters {
	def filters = {
		// action is a regular expression!
		adminOnly( controller: '*', action: "(create|edit|update|delete|save)") {
			before = {
				if( !session?.user?.admin ) {
					redirect( controller: "login", action: "index" )
					return false
				}
			}
			after = {
				// ...do something after controller is called, but before view is rendered...
			}
			afterView = {
				// ...do something after view is rendered...
			}
		}
	}
}

GSPs

Conditional operators used for session access

<g:if test="${session?.user?.admin}">
<!-- Escape $ if expression is in template and should not be evaluated. -->

Create a link to an action in a controller

<g:link controller="controller" action="action">Click here</g:link>
${createLink(controller: 'search')}

Include partial template

<!-- "/subdir/filename" is actually "/views/subdir/_filename.gsp" -->
<g:render template="/subdir/filename" />

Recommended reading