Grails - 简单有很多问题 - 在create.gsp中使用CheckBox而不是HTML Select

gav*_*gav 7 grails save has-many

我的问题是这样的:我想创建一个grails域实例,定义它拥有的另一个域的'Many'实例.我在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)
  }
}
Run Code Online (Sandbox Code Playgroud)

如果您使用此模型并使用def scaffold两个控制器,那么您最终会得到一个不起作用的表单;

脚手架

我自己尝试将此功能列为复选框,并且看起来像这样;

自定义Create.gsp

但是当我拯救志愿者时,技能无效!

无法保存技能

这是我的save方法的代码;

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])
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的日志输出(我有自定义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 ] ]] 
Run Code Online (Sandbox Code Playgroud)

请注意,在最终的日志行中,已经拾取了正确的技能并且它们是对象实例的一部分.当志愿者被保存时,"技能"被忽略并且没有被提交到数据库,尽管内存版本明确地创建了项目.是否不可能在施工时通过技能?这有必要绕道吗?我需要一个表单来允许一个人注册,但我想规范化数据,以便我可以在以后添加更多技能.

如果您认为这应该"正常工作",那么链接到一个工作示例会很棒.

如果我使用HTML Select那么它工作正常!如下面的Make页面;

<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>   
Run Code Online (Sandbox Code Playgroud)

但是我需要它来处理像这样的复选框 ;

<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> 
Run Code Online (Sandbox Code Playgroud)

日志输出完全相同!使用两种形式的格式,可以使用"技能"变量中正确引用的技能创建志愿者实例.保存时,后者失败并显示空引用异常,如此问题顶部所示.

希望这是有道理的,提前谢谢!

GAV

fab*_*474 5

create.gsp <g:checkbox...>代码替换为:

<g:checkBox name="skill_${skillInstance.id}"/>
Run Code Online (Sandbox Code Playgroud)

然后在save控制器的操作内部,替换def volunteerInstance = new Volunteer(params)为:

def volunteerInstance = new Volunteer(name: params.name)
params.each {
  if (it.key.startsWith("skill_"))
    volunteerInstance.skills << Skill.get((it.key - "skill_") as Integer)
}
Run Code Online (Sandbox Code Playgroud)

应该管用.(代码未经测试)