Monday, January 19, 2009

Cool way to dynamically add entries to a list on create in grails

Hi all

A good friend had problem recently with adding items to list opon first create in grails. The problem is how can you set the property of an item as position x in a list if it does not yet exist at that position. Well will with a little magic and grails we did this.

The answer is Lazylist and Lazymap implementations from the commons collection package. So we end up with this result.

import org.apache.commons.collections.Factory;
import org.apache.commons.collections.ListUtils;

public class Requirement {

String label;
List requirements =
new ListUtils.lazyList(new ArrayList(),{new Requirement()} as Factory)

static hasMany = [requirements:Requirement];


static constraints = {
label(blank:false);
}

}


This means in your create form page you can have an entry like this:

<g:textField name="requirements[${i}].label" value=""/>


When you create a Requirement object like this in the controller action.

Requirement r = new Requirement(params)


The new entries will be created in the collection and the label value on them set. The same thing can be done with LazyMap.

enjoy :)

Tuesday, January 13, 2009

Implementing interfaces in Groovy

This a quick post just to put some facts out there after i read this post.

In the post the Vita states that "In Groovy when your class implements a Java interface it must have all the methods present"

Well this is NOT exactly true. Here is an example below of me implementing only the interfaces i want:

This is my very simple interface with 3 methods;

public interface SaySomething {

String saySomethingTrue();

String saySomethingFalse();

String saySomethingFunny();
}


In Groovy you easily implement a multi-method interface with a Map (method name = closure)

So i have code like this. I ONLY implement the methods i want.

SaySomething saySomething = [saySomethingTrue:{'Groovy rocks'},
saySomethingFalse:{'Groovy must implement all methods in a Java interface.'},] as SaySomething;

println "This is true: " + saySomething.saySomethingTrue();

println "This is false: " + saySomething.saySomethingFalse();


As you can see in quick example above i don't provide an implementation for saySomethingFunny()

The result of running this is:

This is true:  Groovy rocks
This is false: Groovy must implement all methods in a Java interface.


UPDATE...

If you just want to do the same thing for all methods:

SaySomething saySomething2 = {return "I am handling all methods"} as SaySomething

println "This is true: " + saySomething2.saySomethingTrue();

println "This is false: " + saySomething2.saySomethingFalse();

println "This is funny: " + saySomething2.saySomethingFunny();


This prints out:

This is true:  I am handling all methods
This is false: I am handling all methods
This is funny: I am handling all methods

Thursday, January 8, 2009

Most powerful agile principal YAGNI

So i have been practicing agile software development for a while now and there are lots of powerful concept that i use during development:

  • Time boxed iterations
  • No big up front design
  • Design evolution
  • Test Driven development
  • Pair programming
  • User stories
  • Refactoring
Many of the power of these concepts have the sum is greater than the parts effect. When they are used in unison the become even more powerful kind of like the power rangers.

Anyway one of the most powerful concepts is YAGNI(You ain't gonna need it). It is so simple in many ways yet so powerful. It is really a kind of extension to another XP principal "do the simplest thing that works". The idea at the micro level is that a code feature should do enough to pass the unit test and integration tests and NO more. Anymore that is over engineering.

The idea being that is is silly to do work today for something you think you MIGHT need tomorrow. Rather take the view you can't predict the future and that you probably WON'T need that feature in the future when the future come. Instead in the future you will learn something new and want a different feature. So although "do the simplest thing that works" principal is powerful at the code level... YAGNI can be applied all over.

The Grails framework is great example of applying the YAGNI principal. It uses convention over configuration because You Ain't Gonna Need configuration.

YAGNI problems: Hard to adapt because of old habits.

It can be hard for older developers to adapt to YAGNI because traditional software development encourages you to make your code generic and reusable, to be able to do everything even make the coffee. However reusable application code is a myth. YAGNI is also hard to measure. How do you measure the time you have not spend on doing something. YAGNI can also be boring for some developers. Some developers like yak shave as in find the most complicated (but stimulating) way to solve a problem.

My suggestion for this is. Just do YAGNI. Don't try, just do. As YODA says there is no try only do or do not!!!.

Once you start doing YAGNI your joy and motivation will come from building things that people want and not what you think they want. More people will use your software and will benefit from it. It will also reduce the 80/20 rule where 80% of people use only 20% of the features. Finally you will actually ship software fancy that.

Once you start practicing YAGNI. You can start applying it to your life. Use it for things like:

  • Packing your suit case for holiday.
  • Ordering food at a restaurant
  • Life insurance :)
You get the idea.

One more thought:

Henry Ford once said: "if i asked the people what they wanted they would have said a faster horse"


enjoy :)

Sunday, January 4, 2009

Grails tips for homepage url mapping

Hi anyone who's reading

Heres a little undocumented tip for grails. It is only a small thing and very easy to solve in grails (once you know how) but none the less it did give me some trouble but only in grails years (which are 100 times less than other frameworks ;) )

Anyway i needed to create link to my homepage on my new site. Now this is default page the root or root context (if you have a root context).

eg in development it would be http://server.com/myappname where as in production it would be http://server.com/

So how do you get grails to create a link for you. You can't just use ${createLink(url:'/')} as that is not contextual to the context and so would not work in development as this is harded coded url. Plus you do not have any default controller to link too. So what to do? Well it turns out this very easily solved by creating new controller and urlmapping combination.

Create a new Home Controller:

class HomeController {

def index = {}
}



Then in your grails-app/views/home directory copy your index.gsp

Then create a urlmapping to go with it that links the controller and action to the root url "/".

class UrlMappings {
static mappings = {

"/"(controller:'home',action:'index')

"/$controller/$action?/$id?"{
constraints {
// apply constraints here
}
}

"500"(view:'/error')
}
}



Then finally to create a link to the controller simple do this:

<a href="${createLink(controller:'home',action:'index')}">Home</a>


Hope this helps someone :)