Skip to main content

Session Notes - Grails Quick Start

Presenter: Dave Klein - Author of Grails Quick-Start Guide (Pragmatic Programmers)

  • groovymag - 20% off with code 2gx1
  • Sample App - Java UG Mgmt App
    • Domain model:
      • Speaker
      • Meeting
      • Sponsor
      • Member (member data already in legacy db)
  • Groovy properties
    • by declaring, they automatically have get/set methods generated
    • can override these if you need to implement something specific in get/set
    • when you access properties via dot notation, behind the scenes it's calling get/set
  • constraints
    • these determine the order in which things are listed in the list and form views
    • by default string fields get 255 varchar in the database
    • if you use a maxSize in the constraints this gives you a textarea on the edit page and a larger text data type in the db
  • toString method
    • by default this will be the class name and the ID
    • good idea to override so toString calls output something more useful
    • particularly helpful with drop-down lists since grails calls toString() on domain classes when generating drop-downs
  • custom validators
    • use groovy code to implement your own validation
    • can be inline in the constraints block or can be a separate closure
    • def meetingTimeValidator { val, obj ->
      def gc = new GregorianCalendar()
      gc.time = val
      gc.get(Calendar.HOUR) == 18 } // ensures meeting time is at 6 pm
  • unit tests
    • mockDomain() -- allows to test domain classes in an isolated manner
      • e.g. mockDomain(Meeting, []) -- this gives you an empty list and will be what's accessed in your unit tests
      • this also gives you all the dynamic methods (GORM, validate(), etc.) in your mocked domain
    • remember that stubbed out tests will pass even though you haven't implemented them, so you'll see passing tests when you run your tests even though they aren't doing anything
    • unit tests run quite a bit faster than integration tests
  • using a "real" db
    • just drop JAR for db drivers in lib directory and set the JDBC URL
    • dev, test, and production environments in DataSource config file
    • for production recommend using JNDI so you don't have to store user name and password in the config file
  • mapping to existing data
    • e.g. member table--id field is member_num; Grails by default uses "id" as the id field name
    • other fields change to all lowercase and add underscores between words, e.g. firstName becomes first_name
    • table names by default are domain name singular (e.g. member not members)
    • if all this doesn't match up, need to add a mapping block to the domain class
      • in case of Member class, id and email fields aren't named correctly, and the table name is plural
    • static mapping = {
      table 'members'
      version false // grails adds this to all your tables; used for optimistic concurrency
      id column: 'member_num'
      columns {
      email column: 'email_address'
    • can use existing Hibernate XML mapping files instead of using DSL for mapping on a class-by-class basis
    • in this case a new field was added to an existing table; grails updated the schema but didn't alter the existing fields in the table
    • basically will always add new fields and will make any other changes based on constraints if the changes are non-destructive
      • e.g. won't shorten the length of an existing field
  • init block in Bootstrap
    • great place to stick test data--generate data so it's available when the app fires up when you're using the in-memory dev db
    • can check environments in bootstrapper so it will do specific things based on the environment the app is running in
    • new in Grails 1.2 is failOnError in save method
  • generate-all command
    • can do grails generate-all "*" to generate controllers, views, and tests for all domain classes
  • grails 1.2 uses tomcat instead of jetty for servlet container
    • also in 1.2 much of what was previously built in is now plugins--1.2 start page shows installed plugins
  • using multiple datasources in a grails app
    • a bit messy--lose a lot of the GORM methods on anything other than the primary datasource
  • can combine create forms across domain classes
    • e.g. in the meeting form, can add the fields to create the speaker on the fly
    • refer to other domain class (speaker in this case) using dot notation:
      <g:textField name="speaker.firstName" value="${meetingInstance?.speaker?.firstName}" />
  • save methods in controllers
    • params is a map containing all the fields from the submitted page
    • params will map directly to domain classes in constructors
      • e.g. def meeting = new Meeting(params)
        • maps all the params by name to the Meeting domain class properties
        • if you have nested classes, e.g. speaker, sponsor, maps those as well
      • you do need to save the objects in order for the final save to work correctly
    • if you want to manually flush the hibernate session pass flush:true to the save method
    • flash scope used for storing data for the current request and the request immediately following
      • easier than using session and having to clear it out later
    • validation happens automatically when save() is called, but you can call it explicitly as well
    • controller actions are transactional by default, but you can control this explicitly as well
  • services
    • these are spring beans
    • autowired by name
      • to use, def myController
    • can inject into controllers, domain classes, taglibs
    • help keep controllers cleaner and leaner
    • not the right place for the domain logic (avoid anemic domain syndrome)
    • can create manually or use grails create-service
    • generation script by default sets all service methods to be transactional
      • if one service method calls another, it will be transactional
    • PersonService used in conjunction with Member, but there's no person class
      • works because in Groovy, don't need to use inheritance -- all by behavior
  • plugins
    • over 300 plugins available
    • 47 javascript plugins
    • 21 security plugins
    • 36 css plugins
    • easy to install -- grails install-plugin pluginName
  • grails ui plugin -- based on YUI library
    • provides
      • DataTable
      • Dialog
      • Auto-Complete
      • Accordian control
      • more
    • e.g. better date picker than default drop-downs used for selecting dates
      • just replace g:datePicker with gui:datePicker in gsp pages
      • declare the tablib and the specific resources being used on each page
        • this way it only loads what you need
      • this returns the date to the controller as a string, so have to modify the controller a bit
        • params.dateTime = new Date().parse("MM/dd/yyyy hh:mm", params.dateTime)
        • default grails datepicker does this step automatically
  • url mapping
    • create more meaningful urls
    • help to hide implementation details
    • gateway to REST in grails
    • e.g. find meeting by year and month
    • update show action to support new url mapping
      • def show = {
        def meetingInstance
        if (params.year) {
        meetingInstance = findMeetingByMonthAndYear(params)
        } else {
        meetingInstances = Meeting.get(
  • gsp tags
    • build reusable components
    • get code out of the view
    • make pages more readable/maintainable
    • encapsulate domain knowledge
    • very easy to create


Anonymous said…
Hi Matthew,Is the code for doing these things in your pragmatic book on grails? I am specifically interested in can combine create forms across domain classes* e.g. in the meeting form, can add the fields to create the speaker on the fly * refer to other domain class (speaker in this case) using dot notation: <g:textfield />
Matthew Woodward said…
Hi Alfred--just so it's clear I didn't write the Grails Quick Start; Dave Klein is the author of the book. I highly, highly recommend it. It's one of the better tech books I've ever read period, and the absolute best way to dive into Grails. Graeme Rocher and Jeff Brown's "Definitive Guide to Grails" (second edition) is also fantastic.

Popular posts from this blog

Installing and Configuring NextPVR as a Replacement for Windows Media Center

If you follow me on Google+ you'll know I had a recent rant about Windows Media Center, which after running fine for about a year suddenly decided as of January 29 it was done downloading the program guide and by extension was therefore done recording any TV shows.

I'll spare you more ranting and simply say that none of the suggestions I got (which I appreciate!) worked, and rather than spending more time figuring out why, I decided to try something different.

NextPVR is an awesome free (as in beer, not as in freedom unfortunately ...) PVR application for Windows that with a little bit of tweaking handily replaced Windows Media Center. It can even download guide data, which is apparently something WMC no longer feels like doing.

Background I wound up going down this road in a rather circuitous way. My initial goal for the weekend project was to get Raspbmc running on one of my Raspberry Pis. The latest version of XBMC has PVR functionality so I was anxious to try that out as a …

Setting Up Django On a Raspberry Pi

This past weekend I finally got a chance to set up one of my two Raspberry Pis to use as a Django server so I thought I'd share the steps I went through both to save someone else attempting to do this some time as well as get any feedback in case there are different/better ways to do any of this.

I'm running this from my house (URL forthcoming once I get the real Django app finalized and put on the Raspberry Pi) using I don't cover that aspect of things in this post but I'm happy to write that up as well if people are interested.

General Comments and Assumptions

Using latest Raspbian “wheezy” distro as of 1/19/2013 (’lll be using Nginx ( as the web server/proxy and Gunicorn ( as the WSGI serverI used heavily as I was creating this, so many thanks to the author of that tutorial. If you’re looking for more details on …

The Definitive Guide to CouchDB Authentication and Security

With a bold title like that I suppose I should clarify a bit. I finally got frustrated enough with all the disparate and seemingly incomplete information on this topic to want to gather everything I know about this topic into a single place, both so I have it for my own reference but also in the hopes that it will help others.Since CouchDB is just an HTTP resource and can be secured at that level along the same lines as you'd secure any HTTP resource, I should also point out that I will not be covering things like putting a proxy in front of CouchDB, using SSL with CouchDB, or anything along those lines. This post is strictly limited to how authentication and security work within CouchDB itself.CouchDB security is powerful and granular but frankly it's also a bit quirky and counterintuitive. What I'm outlining here is my understanding of all of this after taking several runs at it, reading everything I could find on the Internet (yes, the whole Internet!), and a great deal…