Вот метод обслуживания, который я использовал для проверки и сохранения, но регистрировал разрешенные сообщения проверки при сбое.Полезно использовать это вместо просто 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
}
}
}
}
Это зависит от 'журналапеременная, находящаяся в области видимости, которая будет верна в любом артефакте Грааля.Это немного меняет использование контроллера:
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()
.