我有一个域类,它需要在其其中一个字段中创建日期之后有一个日期。
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"
}
您可以检查id
是否设置为指示它是新的非持久性实例还是现有的持久性实例的指示器:
startDate(validator:{ date, obj ->
if (obj.id) {
// don't check existing instances
return
}
def now = new Date()
...
}
一种选择可能是指定要验证的属性。从文档中:
验证方法接受 可选的列表参数,可以 包含属性的名称 这应该得到验证。当列表 传递给验证方法,仅 列表中定义的属性 将被验证。
例:
// 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)
。它肯定会在未来造成一些不可预见的负面后果,除非你非常小心地使用它。如果您能找到替代方案,请务必使用它。