如何为Grails域类中的两个字段创建和XOR验证?

Geo*_*fin 5 grails grails-validation grails-domain-class

我有一个问题,我的域类有两个潜在的互斥外部密钥,序列号或遗留查找值.

由于我不确定任何给定条目我将拥有哪一个,我已经使它们都可以为空并添加自定义验证以确保我只有一个值.

package myproject 

class Sample {

    String information
    String legacyLookup
    String serialNumber

    static constraints = {
        information(nullable: true)
        legacyLookup(nullable: true)
        serialNumber(nullable: true)

        legacyLookup validator: {
            return ((serialNumber != null && legacyLookup == null) || (serialNumber == null && legacyLookup != null))
        }

        serialNumber validator: {
            return ((serialNumber != null && legacyLookup == null) || (serialNumber == null && legacyLookup != null))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了默认的CRUD屏幕,并尝试为此域类创建一个条目

information: Blah Blah
serialNumber: 
legacyLookup: BLAHINDEX123
Run Code Online (Sandbox Code Playgroud)

这在验证器中死亡,并带有以下消息:

No such property: serialNumber for class: myproject.Sample
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Kel*_*lly 9

在那里多次拥有每个财产是没有必要的; 实际上你只需要其中一个实际受约束.此外,您不能直接通过名称引用属性.传递给约束闭包的对象用于获取值(请参阅文档).可能我发现这样做最简单的方法如下:

class Sample {
    String information
    String legacyLookup
    String serialNumber

    static constraints = {
        information(nullable: true)
        legacyLookup(validator: {val, obj->
            if( (!val && !obj.serialNumber) || (val && obj.serialNumber) ) {
                return 'must.be.one'
            }
        })
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在messages.properties文件中有一个条目,如下所示:

must.be.one=Please enter either a serial number or a legacy id - not both
Run Code Online (Sandbox Code Playgroud)

或者你可以为每个条件分别发送消息 - 两者都输入,或者两者都是空白的,如下所示:

legacyLookup(validator: {val, obj->
    if(!val && !obj.serialNumber) {
         return 'must.be.one'
    }
    if(val && obj.serialNumber) { 
         return 'only.one'
    }
})
Run Code Online (Sandbox Code Playgroud)

然后在message.properties中有两条消息:

only.one=Don't fill out both
must.be.one=Fill out at least one...
Run Code Online (Sandbox Code Playgroud)

如果没有错误,您不需要从约束中返回任何内容......