One way to create a helper method is to create it outside of the filters
closure, and pass the instance in. It doesn't work to pass in this
because that's not the closure but the UserFilters
instance. Instead pass in the closure's delegate
which is where the render
and redirect
methods are added, where the attributes like params
and controllerName
are:
class UserFilters {
def filters = {
// ... other filters ...
adminAllCheck(controller: 'administration', action: '*') {
before = {
doAdminCheck(delegate)
}
}
userListCheck(controller: 'user', action: 'list') {
before = {
doAdminCheck(delegate)
}
}
}
private boolean doAdminCheck(filters) {
if (!filters.session.isAdmin) {
if (accountService.isAdmin()) {
filters.session.isAdmin = true
}
else {
filters.flash.message = 'Non admin'
filters.redirect(controller: 'home', action: 'index')
return false
}
}
true
}
}
You can also use the |
character in the controller
and action
arguments to do common work across controllers. It wouldn't work here directly since you use *
for the admin controller and only apply to the list
action in the user controller, but you can do an explicit controller/action name check for that:
adminCheck(controller: 'administration|user', action: '*') {
if (controllerName == 'user' && actionName != 'list') {
return true
}
// common logic here
}
You could also move the logic to a service and dependency-inject that back in. It's usually not a good idea to mix tiers like that and have HTTP logic in a service, but that would keep the logic in one place. You could use the same trick with the delegate, or just pass in the session/request/response/etc. as needed.