我有一个简单的问题。我需要在域对象上管理hasMany集合。我以为我做得对,但它没有用。我找到了另一篇文章,但它已经过时且不起作用(Handling parameters from dynamic form for one-to-many relationships in grails)
class User{
static hasMany = ['prefs': Preference]
}
class Preference{
Boolean email
Boolean site
Date dateCreated
Date lastUpdated
}
GSP
<g:each var="t" in="${user.prefs}" status="idx">
<li>
<input type='hidden' name="prefs[${idx}].id" value="${t.id}"/>
Email: <g:checkBox name="prefs[${idx}].email" value="${t.email}" />
Site: <g:checkBox name="prefs[${idx}].site" value="${t.site}" /><
</li>
</g:each>
控制器:
log.info(user.prefs)
user.properties = params
if(!user.save()){ ... }
然后出错:
UserController - [偏好:3,偏好:4]
错误2013-06-04 21:54:41,405 [http-bio-8080-exec-12] ERROR errors.GrailsExceptionResolver
处理请求时发生IndexOutOfBoundsException:[POST] / user / prefs - 参数: 首选项[0] .email:
id:2
prefs [1] .site:on
prefs [0] .email:on
_prefs [1] .site:
_prefs [1] .email:
prefs [1] .id:3
_prefs [0] .site:
prefs [0] .site:on
prefs [0] .id:4
索引:1,大小:1。Stacktrace如下:
消息:索引:1,大小:1
答案 0 :(得分:1)
前几天我发现了这个问题。并花了2天时间来解决它。
您必须确保params中的子索引与父对象的顺序相同。在这种情况下,孩子的顺序是[偏好:3,偏好:4]。但params顺序是prefs [0] .id = 4,prefs [1] .id = 3.顺序不同。
我必须在绑定它们之前对参数中的子索引重新排序。
答案 1 :(得分:0)
所以我最终解决了这个问题,这是一种混合方法。 @Meam是正确的,这是一个排序问题,但不是担心排序我只是使用@dmahapatro的方法并将Preference设置为一个列表。关于这一点的附注是List preference
的定义必须在static hasMany
定义之前。或者在尝试创建用户时会出现随机错误。最后,当您最初设置关系时,您必须使用addTo
链接两个...
class User{
List preference
static hasMany = ['prefs': Preference]
}
//another thing I did not know in order to originaly link
//the two when using lists, you have to use addTo...
user.addToPrefs(
new Preference(email: true, site:false)
)
我想提到的最后一件事是<g:checkbox>
中存在一个错误,如果您将其与hasMany一起使用,就像我尝试取消选中该值一样,它将无效。我能够通过处理来自FormTagLib的github的代码来解决这个问题。然后用另一篇文章更新了代码我正在阅读https://stackoverflow.com/a/2942667/256793,它有一个解决方案,但它有点过时了。所以这是更新版本:
//old code
//out << "<input type=\"hidden\" name=\"_${name}\""
//new...
def begin = name.lastIndexOf('.') +1
def tail = name.substring( begin);
out << "<input type=\"hidden\" name=\"${name.replace( tail, "_" + tail )}\" "