可以使用注释来保持Groovy / Grails代码DRY吗?

时间:2013-04-02 03:06:32

标签: grails groovy controller annotations dry

我正在使用Grails 2.2.0建立一个网站,我正在寻找关于保持我的代码DRY的最佳实践/建议。这是我第一次使用Grails,我对Groovy和Grails都有一定的了解,但不是任何定义的专家。我确实来自Java + Spring背景。

我有虚荣网址作为要求。实质上,URI用作查找所需模型的密钥。如果找不到,请重定向到主页。如果确实存在,它将在控制器动作的帮助器中使用(由闭包指示,仅在存在时执行)。这是我当前(工作)来源的清理示例:

UrlMappings.groovy:

"/$groupName/dashboard"(controller: "dashboard", action: "viewAll")
"/$groupName/dashboard/create"(controller: "dashboard", action: "createRecord")
"/$groupName/foo/$action?"(controller: "foo")

BaseController.groovy:

Group requireGroupFromUrl(Closure c) {
  if (params.groupName == null) {
    redirect(controller: "home", action: "index")
    return
  }
  else {
    Group group = Group.findByUrlName(params.groupName)
    if (group == null) {
      redirect(controller: "home", action: "index")
      return
    }

    c.call(group)
  }
}

DashboardController.groovy扩展了BaseController:

def viewAll() {
  requireGroupFromUrl({ Group group -> gymHelper(group)})
}

def viewAllHelper(Group group) {

  // some logic involving 'group'

  def map = [groupInstance: group, /* OTHER CALCULATED/QUERIED PARAMS*/ ]
  render(view: "/groupView", model: map)
}

这很有效。然而,对于所有人都需要辅助方法似乎很奇怪。

从一目了然,似乎过滤器可以完成这项工作,但后来我需要指定哪些路径要从过滤器(/,/ login,/ register等)中排除,这似乎可以保持紧密耦合到UrlMappings中的条目。或者我可以以某种方式使用uri多种模式?例如uri: '*/dashboard/**, */foo/**'?如何向前传递检索到的对象?

使用注释仅使用适用的控制器操作注释的注释,可以更好地实现这一点吗?如果是这样,Aspect可以调用redirect吗?如何将检索到的对象传递给带注释的控制器操作?即。

@GroupRequired
def viewAll() {
  ...
}

1 个答案:

答案 0 :(得分:2)

控制器beforeInterceptor可以干净利落地完成此任务:

abstract class BaseController {
    def beforeInterceptor = {
        if (params.groupName == null) {
            redirect(controller: "home", action: "index")
            return false
        }

        Group group = Group.findByUrlName(params.groupName)
        if (group == null) {
            redirect(controller: "home", action: "index")
            return false
        }

        // put the group into the params object
        // for use in the controllers
        params.group = group
    }
}

class ChildController extends BaseController {
    def myAction() {
        Group g = params.group

        // do things
    }
}