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...
