Grails - 从数据绑定的hasMany关联列表中删除项目?

ecr*_*ane 14 data-binding dns grails groovy associations

Grails提供了自动创建域对象并将其绑定到hasMany列表的功能,如grails用户指南中所述.

因此,例如,如果我的域对象"作者"具有许多"书籍"对象的列表,我可以使用以下标记(来自用户指南)创建和绑定它们:

<g:textField name="books[0].title" value="the Stand" /> 
<g:textField name="books[1].title" value="the Shining" /> 
<g:textField name="books[2].title" value="Red Madder" /> 
Run Code Online (Sandbox Code Playgroud)

在这种情况下,如果指定的任何书籍尚不存在,Grails将创建它们并适当地设置它们的标题.如果指定的索引中已有书籍,则会更新其标题并保存.我的问题是:是否有一些简单的方法可以告诉Grails从数据绑定的"书籍"协会中删除其中一本书?

最明显的方法是省略与要删除的域实例对应的表单元素; 不幸的是,根据用户指南,这不起作用:

然后Grails将在定义的位置自动为您创建一个新实例.如果你"跳过"中间的一些元素......那么Grails会自动在两者之间创建实例.

我意识到特定的解决方案可以设计为命令对象的一部分,或者作为特定控制器的一部分 - 但是,在我的应用程序中,跨多个域对象以及许多不同类型的对象的关联,对此功能的需求会反复出现.因此,一般的解决方案是理想的.有谁知道Grails中是否包含这样的内容?

mla*_*the 12

我自己也遇到过这个问题.这很容易解决.Grails使用java.util.Set来表示列表.您可以使用clear()方法擦除数据,然后添加所需的数据.

//clear all documents
bidRequest.documents.clear()

//add the selected ones back
params.documentId.each() {
    def Document document = Document.get(it)
    bidRequest.documents.add(document)
    log.debug("in associateDocuments: added " + document)
};

//try to save the changes
if (!bidRequest.save(flush: true)) {
    return error()
} else {
    flash.message = "Successfully associated documents"
}
Run Code Online (Sandbox Code Playgroud)

我敢打赌,如果你不想"清除()"所有数据,你可以使用"remove()"方法做同样的事情.


A.A*_*nia 11

从......中去除*

与addTo方法相反,它从关联中删除实例.

例子

def author = Author.findByName("Stephen King")

def book = author.books.find { it.title = 'The Stand' }

author.removeFromBooks(book)
Run Code Online (Sandbox Code Playgroud)


小智 5

有关使用 GORM 删除子对象集合的详细说明,请参阅此博客文章的删除子对象部分 - GORM 陷阱第 2 部分

建议阅读本系列的第 1 部分和第 3 部分。


Mar*_*ren 0

我自己刚刚开始学习 Grails,并认为你的问题对我来说是一个有趣的研究练习。我认为您不能使用传统的数据绑定机制 - 因为它在幕后使用某种惰性映射来填补空白。因此,为了实现您的目标,您的“保存”方法(或者它是一个函数?)不太可能包含以下内容:

def Book = new Book(params)
Run Code Online (Sandbox Code Playgroud)

您需要一种机制来修改控制器的“保存”方法。

经过一番研究,我了解到您可以修改负责生成控制器代码或运行时方法的脚手架模板。您可以通过运行“ grails install-templates ”来获取 Grails 使用的所有模板的副本,并且您需要修改的模板文件称为“ Controller.groovy ”。

因此从理论上讲,您可以通过这种方式修改整个应用程序的“保存”方法。

伟大的!您可能认为现在需要做的就是修改模板中的保存方法,以便它迭代参数映射中的对象条目(例如书籍),并随时保存和删除。


但是,我认为您所需的解决方案实现起来仍然存在很大问题。我的直觉告诉我,有很多原因可以解释为什么你建议的机制是一个坏主意。

出于一个原因,我突然想到你有一个分页的书籍清单。这是否意味着您的“保存”可以删除除当前可见页面之外的整个数据库表?好吧,假设您设法计算出每个页面上显示了多少个项目,如果列表已排序,不再按数字顺序排列,该怎么办 - 您现在要删除什么?

也许表单中的多个提交按钮是更好的方法(例如保存更改、添加、删除)。我没有在 Grails 中尝试过这种事情,但了解actionSubmit应该可以帮助您实现多个提交按钮。我以前确实在 Struts 中做过这种事!

华泰