2016-05-06 1 views
1

Я пытаюсь использовать несколько значений для выбора с помощью <g:select multiple='true'>, но когда я пытаюсь сохранить форму в БД, я получил эту ошибкуНесколько значений в <g:select> ошибке

Property [Languages] of class [class com.Myapp.hr.EmploymentSeeker] with value [french,english] is not contained within the list [[french, english, russian, chinese]] 

вот мой домен :

class EmploymentSeeker { 
Set<String> languages = [] as Set 
static hasMany = [ languages: String ] 
static constraints = { 
languages(nullable:true,inList:Holders.config.languages) 
} 

} 

файл конфигурации:

languages=[ 
'french', 
'english', 
'russian', 
'chinese' 
] 

GSP:

<g:select multiple="true" name="languages" from="${employmentSeekerInstance.constraints.languages.inList}" value="${employmentSeekerInstance?.languages}" valueMessagePrefix="empSeeker.languages" noSelection="['': '']"/> 

что может вызвать эту ошибку?

ответ

1

Как упоминалось в Grails документ:

inList: Ограничивает значение, так что она должна содержаться в данном списке.

Проблема заключается в том, что ваш inList constrant это список строк, но languages от EmploymentSeeker не Строки, это Set.

Если бы это была строка, она будет работать, например:
'french' содержится в ['french','english','russian','chinese']
Но у вас есть Set, так
['french'] не содержится в ['french','english','russian','chinese']

Чтобы заставить его работать с inList, вы должны установить в списке ограничений все комбинации, которые пользователь мог выбрать, например:
[['french'], ['french', 'english'], ['english', 'french'] ...] и так далее.
This Ответ описывает, как архивировать эти комбинации, но на самом деле это нехорошее решение, потому что subsequences() не заботится о перестановках. Однако добавление перестановок будет увеличивать ваш список ограничений экспоненциально после расширения списка языков.

Как вы можете видеть, использование inList не является хорошим решением в вашем случае.

Я рекомендую, чтобы реализовать пользовательские простые ограничения, например:

languages(nullable:true,validator: {value, object -> 
       Holders.config.languages.containsAll(value)​​​)​ 
     }) 

Вы можете прочитать о пользовательских ограничений here и here

+0

насчет 'от' в' <г: выбрать несколько = "true" name = "languages" from = "$ {employmentSeekerInstance.constraints.languages.inList}" value = "$ {employmentSeekerInstance? .languages}" valueMessagePrefix = "empSeeker.languages" noSelection = "['': ''] "/>' – Sherif

+0

@Sherif, вы можете использовать список своих оригинальных языков: 'from =" $ {Holders.config.languages} "' –

+0

спасибо, что касается дизайна домена нескольких значений выбора, это то, что я делаю правильно или есть другой удобный способ? – Sherif

Смежные вопросы