如何管理一对多关系-grails

如何管理一对多关系-grails,grails,Grails,我有一个简单的问题。我需要管理域对象上的hasMany集合。我以为我做得对,但没用。我找到了另一个帖子,但它非常过时,不起作用() 普惠制 然后它会出错: 用户控制器-[首选项:3,首选项:4] 错误2013-06-04 21:54:41405[http-bio-8080-exec-12]错误。GrailExceptionResolver 处理请求[POST]/user/prefs-参数时发生IndexOutOfBoundsException: 首选项[0]。电子邮件: id:2 首选项[1]。

我有一个简单的问题。我需要管理域对象上的hasMany集合。我以为我做得对,但没用。我找到了另一个帖子,但它非常过时,不起作用()

普惠制

然后它会出错:

用户控制器-[首选项:3,首选项:4]

错误2013-06-04 21:54:41405[http-bio-8080-exec-12]错误。GrailExceptionResolver

处理请求[POST]/user/prefs-参数时发生IndexOutOfBoundsException: 首选项[0]。电子邮件:
id:2
首选项[1]。站点:位于
首选项[0]。电子邮件:在
_首选项[1]。站点:
_prefs[1]。电子邮件:
prefs[1]。id:3
_首选项[0]。站点:
首选项[0]。站点:位于
prefs[0]。id:4
索引:1,大小:1。堆栈跟踪如下:
消息:索引:1,大小:1



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

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


在绑定参数之前,我必须对参数中的子索引重新排序。

因此我最终解决了这个问题,这是一种混合方法@Meam是正确的,这是一个排序问题,但我没有担心排序问题,而是使用@dmahapatro的方法,将首选项设置为列表。关于这一点的旁注是
列表首选项的定义必须在
静态定义之前。或者,在尝试创建用户时,您将收到一个随机错误。最后,当您最初设置关系时,必须使用
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)
)
我最后要提到的是,
中有一个bug,如果您像我一样将它与hasMany一起使用,那么如果您尝试取消选中该值,它将不起作用。我能够通过处理来自github for的代码来解决这个问题。然后用我读的另一篇文章更新了代码,这篇文章有一个解决方案,但有点过时。以下是更新版本:

 //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  )}\" "
//旧代码

//out设置属性后保存用户是否出错?
user.prefs
的日志从未显示
id
1和2。您能显示控制器代码和POST url吗?顺便说一句,如果您担心gsp中必须显示的特定顺序,请在
User
域中添加
List prefs
。将
prefs
作为项目添加到
User
中的列表中可以维护索引。User.prefs的日志显示
UserController-[Preference:3,Preference:4]
,这两个项恰好是分配的。它没有显示idx,它显示的是surroget键。我们可以看看控制器的动作吗?控制器的哪个部分?我发布了两行操作方法和POST URL。当我测试时,你的设置对我来说非常好,没有任何问题。为了复制这个问题,我正在尝试一行一行地克隆您的安装程序。您是对的,必须有更好的方法来实现这一点。如果顺序正确,我的成功;如果顺序不正确,我的失败。它看起来像是按updateDate随机排序。
log.info(user.prefs)
user.properties = params
if(!user.save()){ ... }
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)
)
 //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  )}\" "