Friday, July 18, 2008

Getting closer

As I'm getting closer to finishing up the essential code for GrailsCrowd, I noticed that I'm doing on the fly refactorings more seamlessly than I was able to do when I first started hacking with Groovy/Grails. And Groovy Closures are my friends these days :-)

Here's a small example from the GrailsCrowd code base - 2 simple controller actions to query for Grails projects by tags, only with the difference that the first action gets all the projects within a system for a specified tag (globally) and the other one gets projects for a tag for a specific member. Both actions operate on the Tag instance, so I refactored the common functionality of querying for Tags into a method which takes a closure:


class GrailsProjectController {

...
private def withTag(callable) {
if (!params.selectedTag) {
redirect(uri: '/notAllowed')
}
def tag = Tag.findByName(params.selectedTag)
callable(tag)
}
...
}


And then the above mentioned actions became:


class GrailsProjectController {

...
def findByTagGlobally = {
def total = 0
def projects = []
withTag {tag ->
if (tag) {
total = Tagging.countByTag(tag)
//Using CrieteriaBuilder here, so we could query by 'taggings' association
projects = GrailsProject.createCriteria().list(params) {
taggings {
eq('tag', tag)
}
} //Criteria builder
//Sort by name since GrailsProject implements Comparable and the name property is its natural order
projects.sort()

} //if
} //Closure
render(view: 'list', model: [projects: projects, navMenu: 'discoverNavigationByTag',
paginatingController: controllerName, paginatingAction: actionName, total: total,
menuContext: [tag: params.selectedTag]])
}

def findByTagForMember = {
def total = 0
def projects = []
def member = Member.findByName(params._name)
withTag {tag ->
if (tag) {
if (!member) {
redirect(uri: '/notAllowed')
}
total = Tagging.countByTagAndMember(tag, member)
//Using CrieteriaBuilder here, so we could query by 'taggings' association
projects = GrailsProject.createCriteria().list(params) {
taggings {
eq('tag', tag)
eq('member', member)
}
} //Criteria builder
//Sort by name since GrailsProject implements Comparable and the name property is its natural order
projects.sort()
} //if
} //Closure
render(view: 'list', model: [projects: projects, navMenu: 'memberProjectsNavigationByTag',
paginatingController: controllerName, paginatingAction: actionName, total: total,
menuContext: [tag: params.selectedTag, member: member]])
}
...
}


Also notice the use of GORM CriteriaBuilder which allowed to nicely query m:n 'Tagging' association class!

Keep Groovying.

Later...

1 comments:

Anonymous said...

Hi,

I keep coming to this website[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url]Plenty of useful information on dima767.blogspot.com. I am sure due to busy scedules we really do not get time to care about our health. In plain english I must warn you that, you are not serious about your health. Recent Research points that about 80% of all United States grownups are either chubby or weighty[url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips].[/url] Therefore if you're one of these individuals, you're not alone. In fact, most of us need to lose a few pounds once in a while to get sexy and perfect six pack abs. Now the question is how you are planning to have quick weight loss? You can easily lose with with little effort. You need to improve some of you daily habbits to achive weight loss in short span of time.

About me: I am webmaster of [url=http://www.weightrapidloss.com/lose-10-pounds-in-2-weeks-quick-weight-loss-tips]Quick weight loss tips[/url]. I am also mentor who can help you lose weight quickly. If you do not want to go under hard training program than you may also try [url=http://www.weightrapidloss.com/acai-berry-for-quick-weight-loss]Acai Berry[/url] or [url=http://www.weightrapidloss.com/colon-cleanse-for-weight-loss]Colon Cleansing[/url] for fast weight loss.