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" />