在grails的多对多关系中使用复选框

在grails的多对多关系中使用复选框,grails,gorm,Grails,Gorm,我在使用复选框时遇到了一个典型的问题。我拥有的是员工和技能。每个员工都可以拥有许多技能,而这些技能可以属于许多员工。这就形成了一种多对多的关系 这是我的域类 class Skill { String name static hasMany = [users:Employee, resources:Resource] static belongsTo = [Employee] static constraints = { name unique:

我在使用复选框时遇到了一个典型的问题。我拥有的是员工和技能。每个员工都可以拥有许多技能,而这些技能可以属于许多员工。这就形成了一种多对多的关系

这是我的域类

class Skill {
    String name
    static hasMany = [users:Employee, resources:Resource]
    static belongsTo = [Employee]

    static constraints = {
        name unique: true, nullable: false, blank: false
    }

    String toString() { return name }
    String getDisplayName() { return name }
}

class Employee {

String name
String surname
Date birthdate
BigDecimal salary
Address address

static hasMany = [skills: Skill]
static belongsTo = [team:Team]

static constraints = {
    address nullable: false, blank: false
    name nullable: false, blank: false, matches: '[a-zA-Z\\-\'\\s]+'
    surname nullable: false, blank: false, matches: '[a-zA-Z\\-\'\\s]+'
    skills nullable: true, blank: true
    salary nullable: false, min: 16000.0, max: 60000.0
    team nullable: true
    birthdate max:new Date(use(TimeCategory){18.years.ago.getTime()})
}

String toString() { return "\nEmployee Information:\n Name: $name\n Surname: $surname\n " +
        "Date of Birth: $birthdate\n Salary: $salary\n"}
}

雇员域工作正常,我可以创建一个地址没有任何问题的雇员

但当我试图向员工添加技能时,它也不会按照我说的做。 例如,当我检查两个特定技能时,它会尝试运行并保存,它会将所有技能添加到员工中

如何告诉控制器仅添加已检查的内容

这是我在控制器中的代码

@Transactional
def create() {
    params.each { println("$it.key -> $it.value") }
    def employee = new Employee(params)
    def address = new Address(params)
    def skills = Skill.list()

    if (params["create"]) {
        if (address.validate()) {
            address.save()
            employee.address = address
            params.remove("_s")
            skills.each { skill -> if (params["s"] != null ) {
                employee.addToSkills(skill)
                }
            }
            if (employee.validate()) {
                employee.save()
                flash.message = "Employee has been successfully created"
                redirect(action: "index")
            }
        } else {
            flash.message = "Ooops Error!!!!"
            render(view: "create", model: [employee: employee, address: address, skill: skills])
        }
    }
    [employee: employee, address: address, skill: skills]
}
这是我的create.gsp

<div class="col-md-6">
<label>Select Your Competences:</label>
   <g:each in="${skill}" var="s" status="i">
    <br/>
    <g:checkBox name="s" value="${s.id}" checked="false"/>
     <label for="s">${s.name}</label>
 </g:each>
 </div>

选择您的能力:

${s.name}
将您的gsp修改为:

<label>Select Your Competences:</label>
   <g:each in="${Skill.list()}" var="skill" status="i">
    <br/>
    <g:checkBox name="s.${skill}" value="${skill.id}" checked="false"/>
     <label for="s">${skill}</label>
 </g:each>
 </div>
现在,在
skillIds
列表中,您有一个
员工的
技能
ID列表, 然后将此消息传递给您的服务,并获取技能以添加到
员工
(使用
Skill.getAll(skillIds)
或其他一些gorm操作)


当使用
g:checkBox
时,您可以在这里看到示例,选中的值是使用带有下划线前缀的名称提交的。在您的情况下,
s
将始终包含所有值,无论是否检查它们。只有
\u s
参数将包含选中的值。这是可行的,但我在控制器中使用了稍微不同的方法
for(skill in params.s){employee.addToSkills(skill.get(skill))}
I代码少了一点,更容易阅读。参数s来自选中的复选框,如果_s将被选中
List<Long> skillIds = new ArrayList<Long>()

  params.skill?.each { s ->

   if(!s.getKey().startsWith("_")) {

    skillIds.add(s.getValue())
   }
  }