关于验证:Grails-字段错误从父类中消失

Grails - Field error disappears from parent class

我有以下问题:

我有一个称为客户的域类,其中嵌入了字段折扣。

1
2
3
4
5
6
7
8
9
10
11
12
    class Customer {
     ...
        String username
        Discount discount
        static constraints = { ... }
    }

    class Discount {
        Integer item1
        Integer item2
        static constraints = { item1 min:1, max:100, nullable:true }
    }

我有一个控制器,可以在其中修改客户的数据。该代码是这样的:

1
2
3
4
5
6
7
8
9
10
11
    def edit() {
        Customer c = Customer.findByUsername(params.userName)
        if(request.method != 'GET'){
            bindData(c, params)
            if(c.validate()) {
                //save the result
            }
        }
        println c.dump()//1
        model:[customer:c]
    }

然后在edit.gsp文件中输入以下代码:

1
2
    ${customer.dump()}//2
    ${customer.discount.dump()}

现在我的问题是,如果我遇到验证错误,例如用户为item1输入123,我将得到适当的错误对象,该对象说当我调用println c.dump()//1时Customer bean在field Discount.item1上存在1个字段错误。

另一方面,在edit.gsp中,customer bean没有任何字段错误,但是customer.discount有提到的错误。这是一个很大的不便,因为我想在像这样的字段旁边显示错误:

1
    <g:renderErrors bean="${customer}" field="discount.item1"/>

但是客户bean没有任何错误,只有折扣bean(因此我没有呈现任何错误)。

你们中的任何人都遇到过这个问题吗?


似乎@Validatable类使用spring框架的AbstractBindingResult的功能,据我所知,它不支持此用法。

但是我能够创建一种解决方法,可以将其用作taglib以实现相同的效果:

给出两个可验证的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Validateable
class TestA {
    TestB b

    static constraints = {
        b validator: {
            it.validate()
        }
    }
}

@Validateable
class TestB {
    int c

    static constraints = {
        c min: 100
    }
}

一个人可以简单地解析bean和属性,并将渲染委托给现有的taglib。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import test.*
import org.codehaus.groovy.grails.plugins.web.taglib.*

ValidationTagLib validationTagLib = ctx.getBean(ValidationTagLib)

renderErrorsWithNestedFields = { attrs, body ->
    def modifiedAttrs = attrs
    String[] path = attrs?.field?.split('\\\\.')
    if(path?.size() > 1) {
        Object resolvedBean
        resolvedBean = attrs.bean
        path[0..-2].each {
            //Some error handling would not hurt, but this is just a proof of concept
            resolvedBean = resolvedBean[it]
        }
        modifiedAttrs = new HashMap(attrs)
        modifiedAttrs.bean = resolvedBean
        modifiedAttrs.field = path.last()
    }
    validationTagLib.renderErrors (modifiedAttrs, null)
}


TestA a = new TestA(b:new TestB(c:3))
a.validate()
renderErrorsWithNestedFields([bean:a, field:'b.c'], null)

这将导致违反c的最小约束的错误。