我的问题是:我想创建一个 grails 域实例,定义它拥有的另一个域的“许多”实例。我在Google 代码项目中有实际来源,但以下内容应说明问题。
class Person {
String name
static hasMany[skills:Skill]
static constraints = {
id (visible:false)
skills (nullable:false, blank:false)
}
}
class Skill {
String name
String description
static constraints = {
id (visible:false)
name (nullable:false, blank:false)
description (nullable:false, blank:false)
}
}
如果您使用此模型并def scaffold
用于两个控制器,那么您最终会得到一个不起作用的表单;
我自己尝试使其工作将技能枚举为复选框,如下所示;
但是当我保存志愿者时,技能无效!
这是我保存方法的代码;
def save = {
log.info "Saving: " + params.toString()
def skills = params.skills
log.info "Skills: " + skills
def volunteerInstance = new Volunteer(params)
log.info volunteerInstance
if (volunteerInstance.save(flush: true)) {
flash.message = "${message(code: 'default.created.message', args: [message(code: 'volunteer.label', default: 'Volunteer'), volunteerInstance.id])}"
redirect(action: "show", id: volunteerInstance.id)
log.info volunteerInstance
}
else {
render(view: "create", model: [volunteerInstance: volunteerInstance])
}
}
这是我的日志输出(我有自定义 toString() 方法);
2010-05-10 21:06:41,494 [http-8080-3] INFO bumbumtrain.VolunteerController - Saving: ["skills":["1", "2"], "name":"Ian", "_skills":["", ""], "create":"Create", "action":"save", "controller":"volunteer"]
2010-05-10 21:06:41,495 [http-8080-3] INFO bumbumtrain.VolunteerController - Skills: [1, 2]
2010-05-10 21:06:41,508 [http-8080-3] INFO bumbumtrain.VolunteerController - Volunteer[ id: null | Name: Ian | Skills [Skill[ id: 1 | Name: Carpenter ] , Skill[ id: 2 | Name: Sound Engineer ] ]]
请注意,在最后的日志行中,正确的技能已被拾取并且是对象实例的一部分。当志愿者被保存时,“技能”被忽略并且没有提交到数据库中,尽管创建的内存版本清楚地确实有这些项目。施工时不能通过技能吗?一定有办法解决这个问题?我需要一个表格来允许一个人注册,但我想规范化数据,以便以后可以添加更多技能。
如果您认为这应该“正常工作”,那么指向工作示例的链接会很棒。
如果我使用 HTML Select,那么它可以正常工作!如以下制作创建页面;
<tr class="prop">
<td valign="top" class="name">
<label for="skills"><g:message code="volunteer.skills.label" default="Skills" /></label>
</td>
<td valign="top" class="value ${hasErrors(bean: volunteerInstance, field: 'skills', 'errors')}">
<g:select name="skills" from="${uk.co.bumbumtrain.Skill.list()}" multiple="yes" optionKey="id" size="5" value="${volunteerInstance?.skills}" />
</td>
</tr>
但我需要它来处理这样的复选框;
<tr class="prop">
<td valign="top" class="name">
<label for="skills"><g:message code="volunteer.skills.label" default="Skills" /></label>
</td>
<td valign="top" class="value ${hasErrors(bean: volunteerInstance, field: 'skills', 'errors')}">
<g:each in="${skillInstanceList}" status="i" var="skillInstance">
<label for="${skillInstance?.name}"><g:message code="${skillInstance?.name}.label" default="${skillInstance?.name}" /></label>
<g:checkBox name="skills" value="${skillInstance?.id.toString()}"/>
</g:each>
</td>
</tr>
日志输出完全一样!使用这两种形式的形式,志愿者实例都是使用在“技能”变量中正确引用的技能创建的。保存时,后者因空引用异常而失败,如本问题顶部所示。
希望这是有道理的,在此先感谢!
加夫