grails中是否有任何成语可以帮助我们保存域对象?
例如
我可能想做类似
的事情
if(candidate.hasErrors || !candidate.save)
{
candidate.errors.each {
log it
}
但是我不想在我做domainObject.save的所有地方传播逻辑。
我也不想要像我所说的那样传递这个domainObject的单独的类,并且放入这个逻辑
由于 苏达
答案 0 :(得分:4)
这是我用来验证和保存的服务方法,但是在失败时记录已解析的验证消息。使用它而不仅仅是println error
或log.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()
。