Skip to main content

Session Notes - Grails Quick Start

Presenter: Dave Klein - Author of Grails Quick-Start Guide (Pragmatic Programmers)
http://gquick.blogspot.com
http://twitter.com/daveklein

  • 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
    • http://grails.org/plugin/home
  • 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(params.id)
        }
        }
  • gsp tags
    • build reusable components
    • get code out of the view
    • make pages more readable/maintainable
    • encapsulate domain knowledge
    • very easy to create

Comments

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

Running a Django Application on Windows Server 2012 with IIS

This is a first for me since under normal circumstances we run all our Django applications on Linux with Nginx, but we're in the process of developing an application for another department and due to the requirements around this project, we'll be handing the code off to them to deploy. They don't have any experience with Linux or web servers other than IIS, so I recently took up the challenge of figuring out how to run Django applications on Windows Server 2012 with IIS.

Based on the dated or complete lack of information around this I'm assuming it's not something that's very common in the wild, so I thought I'd share what I came up with in case others need to do this.


This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

Assumptions and CaveatsThe operating system is Windows Server 2012 R2, 64-bit. If another variant of the operating system is being used, these instructions may not work properly.All of the soft…

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 …

Fixing DPI Scaling Issues in Skype for Business on Windows 10

My setup for my day job these days is a Surface Pro 4 and either an LG 34UC87M-B or a Dell P2715Q monitor, depending on where I'm working. This is a fantastic setup, but some applications have trouble dealing with the high pixel density and don't scale appropriately.
One case in point is Skype for Business. For some reason it scales correctly as I move between the Surface screen and the external monitor when I use the Dell, but on the LG monitor Skype is either massive on the external monitor, or tiny on the Surface screen.
After a big of digging around I came across a solution that worked for me, which is to change a setting in Skype's manifest file (who knew there was one?). On my machine the file is here: C:\Program Files\Microsoft Office\Office16\LYNC.EXE.MANIFEST
And the setting in question is this:
<dpiAware>True/PM</dpiAware>
Which I changed to this: <dpiAware>False/PM</dpiAware>
Note that you'll probably have to edit the file as administr…