Mój problem polega na tym: Chcę utworzyć instancję domeny grails, definiując "wiele" wystąpień innej domeny, która ma. Mam rzeczywiste źródło w Google Code Project, ale poniższe powinny zilustrować problem.Grails - Simple hasMany Problem - Używanie CheckBoxów zamiast HTML Wybierz w create.gsp
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)
}
}
Jeśli używasz tego modelu i def scaffold
dla dwóch kontrolerów wtedy skończyć z postaci jak to, że nie działa;
Moja własna próba uzyskania to do pracy wylicza umiejętności wyboru i wygląda następująco;
Ale kiedy zapisać wolontariusza umiejętności są nieważne!
Jest to kod dla mojego ratowania metodą;
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])
}
}
To jest moje wyjście dziennika (mam niestandardowe metody 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 ] ]]
Należy zauważyć, że w końcowej linii dziennika odpowiednie umiejętności zostały zebrane i są częścią instancji obiektu. Po zapisaniu wolontariusza "Umiejętności" są ignorowane i nie są przypisywane do bazy danych, mimo że w utworzonej pamięci wyraźnie widać elementy. Czy nie jest możliwe przekazanie Umiejętności w czasie budowy? Musi być na to sposób? Potrzebuję jednego formularza, aby umożliwić rejestrację, ale chcę znormalizować dane, aby móc później dodać więcej umiejętności.
Jeśli uważasz, że powinno to po prostu zadziałać, link do działającego przykładu byłby świetny.
Jeśli używam HTML Select, to działa dobrze! Takich jak poniżej, aby utworzyć stronę Utwórz;
<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>
Ale potrzebuję go do pracy z wyboru, takie jak ten;
<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>
Wyjście dziennika jest dokładnie takie samo! W obu wersjach formularza instancja wolontariusza jest tworzona razem z umiejętnościami prawidłowo wymienionymi w zmiennej "umiejętności". Podczas zapisywania ten ostatni kończy się niepowodzeniem z zerowym odwołaniem do odwołania, jak pokazano na górze tego pytania.
Mam nadzieję, że to ma sens, z góry dzięki!
Gav
ratownik! To był taki ból głowy. – gav
Witaj :-) – fabien7474
Mała optymalizacja - it.key.startsSith jest lepszy niż it.key.contains – mmigdol