0

我有一个简单的问题。我需要管理域对象上的 hasMany 集合。我以为我做得对,但它没有用。我发现了另一篇文章,但它非常过时并且不起作用(为 grails 中的一对多关系处理动态表单中的参数

class User{
   static hasMany = ['prefs': Preference] 
}
class Preference{
  Boolean email
  Boolean site
  Date dateCreated
  Date lastUpdated

}

普惠制

<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] 错误错误。处理请求时发生 GrailsExceptionResolver

IndexOutOfBoundsException:[POST] /user/prefs - 参数: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。堆栈跟踪如下:
消息:索引:1,大小:1


4

2 回答 2

1

几天前我发现了这个问题。并花了2天时间修复它。

您必须确保 params 中的子索引与父对象的排序相同。在这种情况下,孩子的顺序是 [Preference: 3, Preference: 4]。但是参数顺序是prefs[0].id = 4,prefs[1].id = 3。顺序不同。

在绑定它们之前,我必须在 params 中重新排序子索引。

于 2013-06-05T02:37:06.853 回答
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 一起使用,则会出现一个错误,如果您尝试取消选中该值,它将无法正常工作。我能够通过处理来自 github 的FormTagLib代码来解决它。然后用我正在阅读的另一篇文章更新代码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  )}\" "
于 2013-06-05T23:12:46.293 回答