%title 2010-07-25 20:18:21 %date On Grails :blog:fossil:diary: Working on a rather large project in grails, I've come to realize two things: there is some absolutely amazing software frameworks out there, and some people who write documentation appear to be 3-year-old kids who speak English as a second language. Â The embarrassing part about that is that, since the project is open-source, I could contribute to the documentation very easily, fixing problems that I see and adding where I see fit. Â However, the problem is so large and daunting (and the project I'm working on way more interesting), so instead, I wind up just living with it and searching El Goog over and over again for the same things. I'm going to try to change this as best I can, and I'm going to start by collecting a few nifty tips and tricks I've pulled out of thin air here, and hopefully pull them all together into one place soon enough.
grails-app/services/package/PermissionsService.groovy
class PermissionsService {
static transactional = true
def authenticateService
def groups = [
userCanRead: { group ->
if (group.exclusive) {
if (authenticateService.principal().domainClass in group.members
|| authenticateService.principal().domainClass.id == group.admin.id
|| authenticateService.ifAnyGranted("ROLE_ADMIN")) {
return true
}
} else {
return true
}
},
// ...
]
}
As you can see, the service contains a list of permissions - closures that do a few tests and return true or false - organized into lists in order to separate them into logical groups (in this case, the groups list pertains to the groups domain class, controller, and views). Each closure expects one argument - the object to test the permissions of. This comes in handy for the corresponding TagLib:
grails-app/taglib/package/PermissionsTagLib.groovy
class PermissionsTagLib {
static namespace = "my"
def permissionsService
def withPermission = { attrs, body ->
if (permissionsService."${attrs['class']}"."${attrs['permission']}"(attrs['arg'])) {
out << body()
}
}
}
The tag-lib allows us to write logical tags that will only output data if the user passes the test, i.e:
In a view...
<my:withPermission class="groups" permission="userCanPost" arg="${group}">
Post new topic
</my:withPermission>
After all, it is nice to ask permission...
grails-app/services/package/TagService.groovy
tags.split(/(?!(?<=\\)),/) .collect { it.trim().replaceAll(/\\,/, ",") } .each { if (it.size() > 0) {
obj.tags.each { otag ->
if (it.tag == it) {
// skip if we already have it tagged
return
}
}
def t
if (Tag.countByTag(it) > 0) {
t = Tag.findByTag(it)
} else {
t = new Tag(tag: it).save()
}
obj.addToTags(t).save(flush: true)
}
}
// ...
This way, we can even have commas in tags, via: "foo, bar\, baz" (tags: ["foo", "bar, baz"])
In your service...
// ...
def ListWithRating (Closure c) {
Obj.withCriteria {
and {
c.delegate = delegate
c()
le('rating', maxRating)
}
}
}
In your controller...
// ...
def criteria = {
eq('type', params.type)
}
listService.listWithRating(criteria)
obj.class.toString().split(/\\./)[-1]
) with the comment, along with the object's id, then get it back the same way. Â You can check that the object exists with dynamic class-loading:def object = Class.forName("package.${objectType}", true, Thread.currentThread().getContextClassLoader())
.get(objectId)
That's about all for now, but I'm sure as the project progresses, I'll come up with more and I'll either post about them or collect them somewhere.