问题
I am using Grails 4.0.4 w/ GORM 7.0.7.RELEASE The database I am using is MongoDB
I can successfully run the application and navigate to the create form for the domain class. I can select the value for the singleton field someOtherEnum
. I can multiselect values for the categories
field. When I submit the form, however, I get this message: 'Property categories is type-mismatched'. I used this approach based on the answers to another question posted here, but it's not working for me. I am not using an embedded enum or hasMany
collection like that user.
The controller and service were generated by the generate-all
command.
How to add a multiple enum field to the create and edit forms in Grails 4?
I have an enum located in src/main/groovy/com/project/core/dsl
I am using to populate a multiselect field for a domain class:
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() }
}
The domain class:
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 +
'}';
}
}
In the create.gsp
view, I have this form:
<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>
The domain class Controller:
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 }
}
}
}
The domain object service:
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)
}
回答1:
I was able to get past my error by making the following changes. I added a hasMany statement in DomainObject
static hasMany = [categories: Category]
and I made these changes in the create.gsp
file:
<f:field property="categories">
<g:select
multiple="true"
name="${property}"
from="${Category?.values()}"
optionKey="key"
value="${domainObject?.categories}"
/>
</f:field>
来源:https://stackoverflow.com/questions/63682211/create-form-for-domain-object-with-multiselect-enum-field-fails-with-property-x