Edu*_*ard 6 grails grails-validation grails-domain-class grails-2.0
我有一个表单来创建一个地方.根据国家/地区,省(州,地区)字段是否必需.
当不需要时,我想为null,而不是空字符串.我有代码,使所有空表单字段,null:
def newparams = [:]
place = new Place()
params.each() { k, v ->
if (v instanceof String && place.hasProperty(k)) {
if (!v.trim().length()) {
newparams[k] = null
} else {
newparams[k] = v
}
}
}
place = new Place(newparams)
place.validate()
Run Code Online (Sandbox Code Playgroud)
现在,在地方域中,我在该省有一个验证器:
province validator: {val, obj -> if (obj.country in obj.requiresRegionCountries() && !obj.province) return [province.required]}
Run Code Online (Sandbox Code Playgroud)
有了这个规则,即使是否需要,我总是得到"省不能为空".
我认为这是因为设置的可空验证器默认为false.
如果我添加nullable:true,那么即使省是必需的,也会跳过自定义验证器,并且可以使用空省保存(我认为这是因为它实例化为null)
现在,我需要以某种方式我的自定义验证器,并能够在我的验证器中指定可为空的内容,如下所示:
province validator: {val, obj ->
if (obj.country in obj.requiresRegionCountries() && !obj.province) {
nullable: false
return [province.required] }
else {
nullable: true
}
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能在Grails 2.0.3中实现这一目标?
Edu*_*ard 12
经过大量的研究和反馈,我发现了两个有效的解决方案.一个在控制器中.不要在模型中添加任何验证并从控制器动态添加它们:
class PlacesController {
def create() {
def place = new Place(params.address)
if (place.country in placesThatRequiresProvinceArray) {
place.constrains.province.nullable = false
} else {
place.constrains.province.nullable = true
}
Run Code Online (Sandbox Code Playgroud)
}
另一个解决方案是Tri在这个线程中提出的解决方案,但是将自定义验证器放在可以为空的约束之前(否则不会为空值调用自定义验证器):
static constraints = {
province (validator: {val, obj ->
if (obj.country == 'Canada' && !val)
return ['province.required']
}, nullable: true)
}
Run Code Online (Sandbox Code Playgroud)
我不知道你粘贴的代码,但如果你的问题是默认验证不允许省为null,你是否尝试明确允许省为空?每个字段允许多个验证器.所以回到原始代码中,只需指定可空的验证器:
province nullable: true, validator: {val, obj ->
if (obj != null && obj.country in obj.requiresRegionCountries() && !obj.province)
return [province.required]
}
Run Code Online (Sandbox Code Playgroud)
编辑:在自定义验证器中,可能还希望在if条件中防止obj为null.
EDIT2:演示项目,显示上述验证工作在grails 2.0.4上
class Place {
String country
Province province
static constraints = {
province (nullable: true, validator: {val, obj ->
if (obj.country == 'Canada' && !val) return ['province.required']
})
}
}
Run Code Online (Sandbox Code Playgroud)
控制器...
class MainController {
def index() {
def place = new Place(country: 'Canada')
if (!place.validate()) {
render "need province<br/>" + place.errors
} else {
render "cool"
}
Run Code Online (Sandbox Code Playgroud)
所以我的想法是我有一个虚拟控制器,我可以在其中调用索引操作,该操作是硬编码的,以创建类似于您的示例的Place域实例.请注意,我只定义了国家/地区字符串,因此我可以将其逻辑键入其中以进行自定义验证.我在创建Place实例时没有定义省,所以它应该为null.在这种情况下,响应页面将打印以下内容......
输出片段......
need province
grails.validation.ValidationErrors: 1 .... does not pass custom validation]
Run Code Online (Sandbox Code Playgroud)
如果我从Place中删除nullable:true约束,则错误是预期的空值...
输出片段......
need province
grails.validation.ValidationErrors: 1 .... cannot be null]
Run Code Online (Sandbox Code Playgroud)