Grails:我可以让验证器仅应用于创建(而不是更新/编辑)

发布于 2024-11-05 17:29:48 字数 1018 浏览 5 评论 0原文

我有一个域类,需要在其字段之一中创建它之后有一个日期。

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)
    })
  }
}

因此,几天后,当我仅更改字符串并调用保存时,保存失败,因为验证器正在重新检查日期,而它现在已经过去了。我可以将验证器设置为仅在创建时触发,还是可以通过某种方式更改它来检测我们是否正在创建或编辑/更新?

@罗布H 我不完全确定如何使用您的答案。我有以下代码导致此错误:

myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
  println "This keeps happening because of the stupid date problem"
}

I have a domain class that needs to have a date after the day it is created in one of its fields.

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)
    })
  }
}

So several days later when I change only the string and call save the save fails because the validator is rechecking the date and it is now in the past. Can I set the validator to fire only on create, or is there some way I can change it to detect if we are creating or editing/updating?

@Rob H
I am not entirely sure how to use your answer. I have the following code causing this error:

myInstance.iAmGonnaChangeThisInSeveralDays = "nachos"
myInstance.save()
if(myInstance.hasErrors()){
  println "This keeps happening because of the stupid date problem"
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

坏尐絯 2024-11-12 17:29:48

您可以检查 id 是否设置为指示它是新的非持久实例还是现有持久实例:

startDate(validator:{ date, obj ->
   if (obj.id) {
      // don't check existing instances
      return
   }
   def now = new Date()
   ...
}

You can check if the id is set as an indicator of whether it's a new non-persistent instance or an existing persistent instance:

startDate(validator:{ date, obj ->
   if (obj.id) {
      // don't check existing instances
      return
   }
   def now = new Date()
   ...
}
£冰雨忧蓝° 2024-11-12 17:29:48

一种选择可能是指定要验证哪些属性。来自文档

验证方法接受
可选的列表参数可以
包含属性的名称
这应该得到验证。当一个列表
被传递到 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)。除非您非常小心地使用它,否则它肯定会在未来造成一些不可预见的负面后果。如果您能找到替代方案,请务必使用它。

One option might be to specify which properties you want to be validated. From the documentation:

The validate method accepts an
optional List argument which may
contain the names of the properties
that should be validated. When a List
is passed to the validate method, only
the properties defined in the List
will be validated.

Example:

// 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
}

This feels a bit hacky, since you're bypassing some built-in Grails goodness. You'll want to be cautious that you aren't bypassing any necessary validation on the domain that would normally happen if you were to just call save(). I'd be interested in seeing others' solutions if there are more elegant ones.

Note: I really don't recommend using save(validate: false) if you can avoid it. It's bound to cause some unforeseen negative consequence down the road unless you're very careful about how you use it. If you can find an alternative, by all means use it instead.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文