Я использую Grails 4.0.4 с GORM 7.0.7.RELEASE. Я использую базу данных MongoDB.
Я могу успешно запустить приложение и перейти к форме создания для класса домена. Я могу выбрать значение для одноэлементного поля someOtherEnum
. Я могу выбрать несколько значений для поля categories
. Однако, когда я отправляю форму, я получаю это сообщение: «Категории свойств не соответствуют типу». Я использовал этот подход на основе ответов на другой вопрос, размещенный здесь, но он не работает для меня. Я не использую встроенное перечисление или коллекцию hasMany
, как этот пользователь.
Контроллер и сервис были сгенерированы командой generate-all
.
Как добавить несколько полей перечисления в формы создания и редактирования в Grails 4?
У меня есть перечисление, расположенное в src/main/groovy/com/project/core/dsl
, которое я использую для заполнения поля множественного выбора для класса домена:
package com.project.core.dsl
import groovy.transform.CompileStatic
@CompileStatic
enum Category {
CATEGORY_ONE("Category One"),
CATEGORY_TWO("Category Two"),
CATEGORY_THREE("Category Three")
private final String id
private Category(String id) { this.id = id }
@Override
String toString() { id }
String getKey() { name() }
}
Класс домена:
package com.project.core
import com.project.core.dsl.SomeOtherEnum
import com.project.core.dsl.Category
class DomainObject {
SomeOtherEnum someOtherEnum
Set<Category> categories
static constraints = {
}
static mapping = {
someOtherEnum index: true
}
@Override
String toString() {
return "DomainObject{" +
"someOtherEnum=" + someOtherEnum +
", categories=" + categories +
'}';
}
}
В представлении create.gsp
у меня есть такая форма:
<g:form resource="${this.domainObject}" method="POST">
<fieldset class="form">
<f:with bean="domainObject">
<f:field property="someOtherEnum"/>
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category}"
value="${domainObject?.categories}"
/>
</f:field>
</f:with>
</fieldset>
<fieldset class="buttons">
<g:submitButton name="create" class="save" value="${message(code: 'default.button.create.label', default: 'Create')}" />
</fieldset>
</g:form>
Контроллер класса домена:
package com.project.core
import grails.validation.ValidationException
import static org.springframework.http.HttpStatus.*
class DomainObject {
DomainObjectService domainObjectService
static allowedMethods = [save: "POST", update: "PUT", delete: "DELETE"]
def index(Integer max) {
params.max = Math.min(max ?: 10, 100)
respond domainObjectService.list(params), model:[domainObjectCount: domainObjectService.count()]
}
def show(Long id) {
respond domainObjectService.get(id)
}
def create() {
respond new DomainObject(params)
}
def save(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'create'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.created.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*' { respond domainObject, [status: CREATED] }
}
}
def edit(Long id) {
respond domainObjectService.get(id)
}
def update(DomainObject domainObject) {
if (domainObject == null) {
notFound()
return
}
try {
domainObjectService.save(domainObject)
} catch (ValidationException e) {
respond domainObject.errors, view:'edit'
return
}
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.updated.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), domainObject.id])
redirect domainObject
}
'*'{ respond domainObject, [status: OK] }
}
}
def delete(Long id) {
if (id == null) {
notFound()
return
}
domainObjectService.delete(id)
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.deleted.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), id])
redirect action:"index", method:"GET"
}
'*'{ render status: NO_CONTENT }
}
}
protected void notFound() {
request.withFormat {
form multipartForm {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'domainObject.label', default: 'DomainObject'), params.id])
redirect action: "index", method: "GET"
}
'*'{ render status: NOT_FOUND }
}
}
}
Служба объекта домена:
package com.project.core
import grails.gorm.services.Service
@Service(DomainObject)
interface DomainObjectService {
DomainObject get(Serializable id)
List<DomainObject> list(Map args)
Long count()
void delete(Serializable id)
DomainObject save(DomainObject domainObject)
}
DomainObject
? - person Jeff Scott Brown   schedule 01.09.2020