Grails Controller中的重用标准

时间:2011-02-23 15:18:36

标签: grails closures criteria

通常,Grails生成的Controller列表方法中有以下最后一行:

[userInstanceList: User.list(params), userInstanceTotal: User.count()]

如果我想按照特定条件限制用户,则

[userInstanceList: User.list(params) {
   ilike('login', '%test%')
 }, userInstanceTotal: User.count() {
   ilike('login', '%test%')
 }]

但是这违反了DRY原则 - 重用标准闭包的最佳方法是什么?

3 个答案:

答案 0 :(得分:5)

条件构建器的分页结果(结果类为PagedResultList)具有属性totalCount,您可以像使用相同条件调用count()一样使用该属性:< / p>

def userInstanceList = User.createCriteria().list(params) {
    ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]

答案 1 :(得分:3)

针对这种情况的另一种方法(需要在各种不同的标准查询中重用相同的逻辑),可能是使用groovy闭包,正如您在帖子标题中所述。

使用PagedResultList的totalCount属性可以更好地解决您的特定情况,就像Dana在她的回答中所说的那样。但是,您可能会遇到更复杂的情况,您必须在标准内重用逻辑。对于类似的情况,我已经成功尝试了以下解决方案。以您的案例为例:

def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]

iLikeLoginClosure 中的构建器是对其中调用闭包的条件构建器对象的引用。此外,在iLikeLoginClosure内部,您可以使用闭包内相同范围的变量定义。

这是受到这篇文章的启发:来自MrHaki优秀博客的http://mrhaki.blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html

答案 2 :(得分:2)

您可以使用named queries

在您的域类中:

static namedQueries = {
    ilikeLogin{login->ilike('login', "%$login%")}
}

在您的控制器中:

def userList = User.ilikeLogin('test').list(params)
def usersCount= User.ilikeLogin('test').count()

或者(我不是100%肯定会这样,但试试吧。):

def query = User.ilikeLogin('test')
def userList = query.list(params)
def usersCount= query.count()