【问题标题】:Grails validate fields with default valuesGrails 使用默认值验证字段
【发布时间】:2014-09-20 00:58:12
【问题描述】:

我们在 Grails 2.4.3 应用程序中有一个这样的类(从 2.3.8 迁移而来):

@Validateable
class Foo {
    Integer noDefault;
    Integer withDefault = 1;

    static constraints = {
        noDefault(nullable:false)
        withDefault(nullable:false)
    }
}

这个类在一个复杂的配置机制中被实例化,使用这样的 Map:

[
    noDefault: 0,
    withDefault: 2
]

(实际上 Map 是一个巨大的 Map 的一部分,但类构造函数看到这个小的。)以前,如果我们从配置映射中省略 withDefault 条目,使用不为 null 的默认值,则该类可以工作。然而,在 Grails 2.4.3 中,它告诉我这个字段不能为空。我可以通过让它在约束中为空来修复它,但是它允许将显式值设置为空(并覆盖默认值),这会导致操作过程中出现问题。

您知道一些解决方法,它可以保留语义和正确的操作吗?

提前谢谢,最好的问候:Balázs

【问题讨论】:

  • 您确定您正在绑定的Map 真的不包含withDefault 的值吗?如果它包含一个可以解释您所看到的行为的 null 值。如果 Map 确实不包含 withDefault 的值,那么您所描述的行为对我来说没有意义。一定有其他一些没有在描述中表达的因素。请参阅我在下面发布的代码,如果您可以缩小问题场景的细节,我将很乐意研究它。祝你好运。
  • 在黑暗中随机拍摄,但属性名称 (withDefault) 是否会与 Groovy 的 Map.withDefault() 方法发生冲突?
  • 安德鲁,这对我来说似乎不太可能。所描述的场景是地图中没有任何 withDefault 条目的场景。即使有应该仍然有效,但由于 withDefault 甚至不在地图中,我不知道这有什么关系。

标签: validation grails grails-2.4


【解决方案1】:

您所描述的与我的预期不一致,也与我看到的行为不一致。 https://github.com/jeffbrown/validatedefaults 的项目包含以下代码。

https://github.com/jeffbrown/validatedefaults/blob/master/src/groovy/demo/Foo.groovy

// src/groovy/demo/Foo.groovy
package demo

import grails.validation.Validateable

@Validateable
class Foo {
    Integer noDefault;
    Integer withDefault = 1;

    static constraints = {
        noDefault(nullable:false)
        withDefault(nullable:false)
    }
}

https://github.com/jeffbrown/validatedefaults/blob/master/test/unit/demo/FooSpec.groovy 的测试通过:

// test/unit/demo/FooSpec.groovy
package demo

import spock.lang.Specification
import grails.test.mixin.TestMixin
import grails.test.mixin.support.GrailsUnitTestMixin

@TestMixin(GrailsUnitTestMixin)
class FooSpec extends Specification {

    void 'test validating default values'() {
        given:
        def map = [noDefault: 0]
        def foo = new Foo(map)

        expect:
        foo.validate()
    }
}

当我运行应用程序时,我会得到相同的行为。

// grails-app/conf/BootStrap.groovy
import demo.Foo

class BootStrap {

    def init = { servletContext ->
        def map = [noDefault: 0]
        def foo = new Foo(map)

        // this prints true...
        println "Foo is valid? : ${foo.validate()}"
    }
    def destroy = {
    }
}

希望对你有帮助。

【讨论】:

  • 您的示例有效,并且测试通过了我。我再次尝试了真正的应用程序,这次成功了。原因很神秘——我经常在我的 JVM 上看到无法解释的错误,而且它们甚至会在一天内不断重复。无论我如何做 grailsw clean,删除 workdir 或重新启动系统。 JVM 坏了,重新安装它或其他版本也无济于事。很抱歉这个错误的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多