grails 中保存和更新方法的习惯用法

发布于 2024-10-23 17:45:43 字数 323 浏览 6 评论 0原文

grails 中是否有任何习惯用法可以帮助我们保存域对象?

例如

我可能想做类似的事情


if(candidate.hasErrors || !candidate.save)
{
candidate.errors.each {
        log it

}

但是我不想将逻辑传播到我执行domainObject.save 的所有地方。

我也不想要像存储库这样的单独的类,我将这个domainObject传递给它并放入这个逻辑

谢谢 苏达山

Are there in any idioms in grails which help us with saving domain objects ?

For example

i may want to do something like


if(candidate.hasErrors || !candidate.save)
{
candidate.errors.each {
        log it

}

However i do not want to spread the logic across all the places i do domainObject.save.

I also do not want seperate class like say repo to which I pass this domainObject and put in this logic

Thanks
Sudarshan

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

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

发布评论

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

评论(1

捶死心动 2024-10-30 17:45:43

这是我用来验证和保存的服务方法,但会在失败时记录已解析的验证消息。使用它而不是仅仅使用 println errorlog.warn error 会很有帮助,因为错误对象的 toString() 非常冗长,你只想看看会显示什么关于 GSP:

class MyService {
   def messageSource

   def saveOrUpdate(bean, flush = false) {
      return validate(bean) ? bean.save(flush: flush) : null
   }

   boolean validate(bean) {
      bean.validate()
      if (bean.hasErrors()) {
      if (log.isEnabledFor(Level.WARN)) {
         def message = new StringBuilder(
            "problem ${bean.id ? 'updating' : 'creating'} ${bean.getClass().simpleName}: $bean")
         def locale = Locale.getDefault()
         for (fieldErrors in bean.errors) {
            for (error in fieldErrors.allErrors) {
               message.append("\n\t")
               message.append(messageSource.getMessage(error, locale))
            }
         }
         log.warn message
      }
      bean.discard()
      return false
   }

   return true
}

这是控制器中的一个示例:

class MyController {

   def myService

   def actionName = {
      def thing = new Thing(params)
      if (myService.saveOrUpdate(thing)) {
         redirect action: 'show', id: thing.id
      }
      else {
         render view: 'create', model: [thing: thing]
      }
   }
}

编辑:也可以将这些方法添加到 MetaClass,例如在 BootStrap.groovy 中:

class BootStrap {

   def grailsApplication
   def messageSource

   def init = { servletContext ->

      for (dc in grailsApplication.domainClasses) {
         dc.metaClass.saveOrUpdate = { boolean flush = false ->
            validateWithWarnings() ? delegate.save(flush: flush) : null
         }

         dc.metaClass.validateWithWarnings = { ->
            delegate.validate()
            if (delegate.hasErrors()) {
               def message = new StringBuilder(
                  "problem ${delegate.id ? 'updating' : 'creating'} ${delegate.getClass().simpleName}: $delegate")
               def locale = Locale.getDefault()
               for (fieldErrors in delegate.errors) {
                  for (error in fieldErrors.allErrors) {
                     message.append("\n\t")
                     message.append(messageSource.getMessage(error, locale))
                  }
               }
               log.warn message
               delegate.discard()
               return false
            }

            return true
         }
      }
   }
}

这取决于范围内的“log”变量,这在任何 Grails 中都是如此人工制品。这会稍微改变控制器的用法:

class MyController {

   def actionName = {
      def thing = new Thing(params)
      if (thing.saveOrUpdate()) {
         redirect action: 'show', id: thing.id
      }
      else {
         render view: 'create', model: [thing: thing]
      }
   }
}

作为元类方法,重命名它可能更有意义,例如 saveWithWarnings()

Here's a service method that I've used to validate and save, but log resolved validation messages on failure. It's helpful to use this instead of just println error or log.warn error since the toString() for error objects is very verbose and you just want to see what would be displayed on the GSP:

class MyService {
   def messageSource

   def saveOrUpdate(bean, flush = false) {
      return validate(bean) ? bean.save(flush: flush) : null
   }

   boolean validate(bean) {
      bean.validate()
      if (bean.hasErrors()) {
      if (log.isEnabledFor(Level.WARN)) {
         def message = new StringBuilder(
            "problem ${bean.id ? 'updating' : 'creating'} ${bean.getClass().simpleName}: $bean")
         def locale = Locale.getDefault()
         for (fieldErrors in bean.errors) {
            for (error in fieldErrors.allErrors) {
               message.append("\n\t")
               message.append(messageSource.getMessage(error, locale))
            }
         }
         log.warn message
      }
      bean.discard()
      return false
   }

   return true
}

And here's an example in a controller:

class MyController {

   def myService

   def actionName = {
      def thing = new Thing(params)
      if (myService.saveOrUpdate(thing)) {
         redirect action: 'show', id: thing.id
      }
      else {
         render view: 'create', model: [thing: thing]
      }
   }
}

Edit: It's also possible to add these methods to the MetaClass, e.g. in BootStrap.groovy:

class BootStrap {

   def grailsApplication
   def messageSource

   def init = { servletContext ->

      for (dc in grailsApplication.domainClasses) {
         dc.metaClass.saveOrUpdate = { boolean flush = false ->
            validateWithWarnings() ? delegate.save(flush: flush) : null
         }

         dc.metaClass.validateWithWarnings = { ->
            delegate.validate()
            if (delegate.hasErrors()) {
               def message = new StringBuilder(
                  "problem ${delegate.id ? 'updating' : 'creating'} ${delegate.getClass().simpleName}: $delegate")
               def locale = Locale.getDefault()
               for (fieldErrors in delegate.errors) {
                  for (error in fieldErrors.allErrors) {
                     message.append("\n\t")
                     message.append(messageSource.getMessage(error, locale))
                  }
               }
               log.warn message
               delegate.discard()
               return false
            }

            return true
         }
      }
   }
}

This depends on a 'log' variable being in scope, which will be true in any Grails artifact. This changes the controller usage slightly:

class MyController {

   def actionName = {
      def thing = new Thing(params)
      if (thing.saveOrUpdate()) {
         redirect action: 'show', id: thing.id
      }
      else {
         render view: 'create', model: [thing: thing]
      }
   }
}

As a metaclass method it may make more sense to rename it, e.g. saveWithWarnings().

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