Почти каждое действие контроллера ищет одну или несколько сущностей на основе некоторого пользовательского ввода. В течение некоторого времени я хотел убрать часть этого скучного, ломкого, стандартного кода:
def show = {
def entity = null
if (params.id && params.id.isLong() && params.id.toLong() >= 0)
entity = Book.get(params.id.toLong())
if (!entity) {
flash.message = "Could not find, blah blah blah"
return redirect(...)
}
// Useful code
}
Мой текущий подход предполагает внедрение метода findEntry во все контроллеры.
void injectFindEntryMethod() {
grailsApplication.controllerClasses.each { def c ->
c.metaClass.findDomainEntry = { def domainClass, def entryId ->
def entry = null
if (entryId && entryId.isLong() && entryId.toLong() >= 0)
entry = domainClass.findById(entryId)
if (!entry)
throw new DomainInstanceNotFoundException(domainClass, entryId)
return entry
}
}
}
Основная идея этого метода заключается в том, что он создает исключение, когда запись не может быть найдена. В настоящее время я «ловлю» это исключение, используя функциональность «декларативной обработки ошибок» в Grails 1.1.
"500"(controller: "error", action: 'domainInstanceNotFound', exception: DomainInstanceNotFoundException)
Изюминкой этого решения является то, что раздутый код в действии show уменьшен до:
def show = {
def entry = findDomainEntry(BlogEntry, params.id)
// Useful code
}
К сожалению, это также имеет несколько недостатков, но вот почему у нас есть Stackoverflow, верно? : -)
Проблемы / недостатки:
- Это приведет к регистрации в стеке трассировки исключения, что раздражает, так как я обрабатываю исключение в моем ErrorController.
- Я не могу получить доступ к объекту исключения внутри метода действия, но объект доступен через $ {exception} внутри представления (я не могу понять, почему он реализован таким образом).
Что вы, ребята, думаете об этом подходе? Есть ли способы улучшить это? Какие-нибудь советы или упоминания о недостатках, которые я упомянул выше? Извините, если объем моих вопросов слишком велик, просто нет смысла разбивать их на несколько вопросов.