我有一个域类,需要在其某个字段中创建日期之后有一个日期。
class myClass {
Date startDate
String iAmGonnaChangeThisInSeveralDays
static constraints = {
iAmGonnaChangeThisInSeveralDays(nullable:true)
startDate(validator:{
def now = new Date()
def roundedDay = DateUtils.round(now, Calendar.DATE)
def checkAgainst
if(roundedDay>now){
Calendar cal = Calendar.getInstance();
cal.setTime(roundedDay);
cal.add(Calendar.DAY_OF_YEAR, -1); // <--
checkAgainst = cal.getTime();
}
else checkAgainst = roundedDay
return (it >= checkAgainst)
})
}
}
所以几天后,当我只更改字符串并调用save时,保存失败,因为验证器正在重新检查日期,现在它已经过去了。我是否可以将验证器设置为仅在创建时触发,或者是否有某些方法可以更改它以检测我们是否正在创建或编辑/更新?
@Rob H. 我不完全确定如何使用你的答案。我有以下代码导致此错误:
myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
println "This keeps happening because of the stupid date problem"
}
答案 0 :(得分:13)
您可以检查id
是否设置为指示它是新的非持久性实例还是现有持久性实例:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
答案 1 :(得分:0)
一个选项可能是指定要验证的属性。来自documentation:
validate方法接受 可选的List参数 包含属性的名称 应该验证。当一个List 仅传递给validate方法 列表中定义的属性 将被验证。
示例:
// when saving for the first time:
myInstance.startDate = new Date()
if(myInstance.validate() && myInstance.save()) { ... }
// when updating later
myInstance.iAmGonnaChangeThisInSeveralDays = 'New Value'
myInstance.validate(['iAmGonnaChangeThisInSeveralDays'])
if(myInstance.hasErrors() || !myInstance.save(validate: false)) {
// handle errors
} else {
// handle success
}
这感觉有些笨拙,因为你绕过了一些内置的Grails善良。如果你只是打电话给save()
,你就要小心谨慎,不要绕过域上通常会发生的必要验证。如果有更优雅的解决方案,我会有兴趣看到别人的解决方案。
注意:如果可以避免,我真的不建议使用save(validate: false)
。除非你非常小心你如何使用它,否则它必将导致一些不可预见的负面后果。如果您能找到替代方案,请务必使用它。