TouK contest – some important rules

By entering TouK contest at 33rd Degree Conference you are accepting these simple conditions:

  1. The contest is open to all 33rd Degree Conference participians, except TouK people and their family members, of course (sorry, guys).
  2. To take part, you must collect two TouK feathers (in two different colours) and hack an application. The apllication is avaliable at http://reg.touk.pl. Then you must write down the solution (with your name and surname) on a sheet of paper received at our stand. and leave it to us to enter a prize draw. You must have TouK feathers in both colors with you.
  3. Only one entry is allowed per person.
  4. The prizes are 6 Raspberry Pi computers (2 per each conference day).
  5. All entries (except the winners’) will be rolled over into subsequent draws.
  6. All prize draws take place at our stand in following dates: ·Day 1, 13 of March – 16:30 ·Day 2, 14 of March – 15:50 ·Day 3, 15 of March – 12:50
  7. Only correct and complete solutions will be awarded.
  8. The winner have to be present during the prize draw. If not, we reserve the right to award the prize to an alternative winner, drawn in accordance with these terms and conditions.
  9. If you have any questions about how to enter or in connection with the contest, please ask at TouK’s stand.
You May Also Like

Simple trick to DRY your Grails controller

Grails controllers are not very DRY. It's easy to find duplicated code fragments in default generated controller. Take a look at code sample below. It is duplicated four times in show, edit, update and delete actions:

class BookController {
def show() {
def bookInstance = Book.get(params.id)
if (!bookInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
return
}
[bookInstance: bookInstance]
}
}

Why is it duplicated?

There is a reason for that duplication, though. If you move this snippet to a method, it can redirect to "list" action, but it can't prevent controller from further execution. After you call redirect, response status changes to 302, but after method exits, controller still runs subsequent code.

Solution

At TouK we've implemented a simple trick to resolve that situation:

  1. wrap everything with a simple withStoppingOnRender method,
  2. whenever you want to render or redirect AND stop controller execution - throw EndRenderingException.

We call it Big Return - return from a method and return from a controller at once. Here is how it works:

class BookController {
def show(Long id) {
withStoppingOnRender {
Book bookInstance = Book.get(id)
validateInstanceExists(bookInstance)
[bookInstance: bookInstance]
}
}

protected Object withStoppingOnRender(Closure closure) {
try {
return closure.call()
} catch (EndRenderingException e) {}
}

private void validateInstanceExists(Book instance) {
if (!instance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])
redirect(action: "list")
throw new EndRenderingException()
}
}
}

class EndRenderingException extends RuntimeException {}

Example usage

For simple CRUD controllers, you can use this solution and create some BaseController class for your controllers. We use withStoppingOnRender in every controller so code doesn't look like a spaghetti, we follow DRY principle and code is self-documented. Win-win-win! Here is a more complex example:

class DealerController {
@Transactional
def update() {
withStoppingOnRender {
Dealer dealerInstance = Dealer.get(params.id)
validateInstanceExists(dealerInstance)
validateAccountInExternalService(dealerInstance)
checkIfInstanceWasConcurrentlyModified(dealerInstance, params.version)
dealerInstance.properties = params
saveUpdatedInstance(dealerInstance)
redirectToAfterUpdate(dealerInstance)
}
}
}