我是Grails的初学者,当我尝试保存POGO时遇到问题
我创建了1个域类
class Book {
String title
}
然后,我自动生成了控制器和视图。 现在,我希望能够通过单击“创建”创建一本包含代码的书(我知道可以直接使用生成的代码,但对于我的示例,我想通过代码来完成)。为此,我在控制器中修改了“save(Book bookInstance)”方法,就像这样
@Transactional
def save(Book bookInstance) {
def book = new Book(title:"New Grails Book").save()
但是,当我转到URL localhost:8080 / myApp / book / create然后我点击“创建”时,我有错误
message -> /myApp/WEB-INF/grails-app/views/book/save.jsp
description -> The requested resource is not available.
当我把这段代码放在bootStrap中时,没关系,所以我不明白为什么它不在控制器中
答案 0 :(得分:4)
如果域类中有hasMany
属性,Grails会向域类添加Set
属性并进行AST转换(因此它实际上存在于字节码中,并且可以看到Java)表示集合,当您添加belongsTo
时,会添加该类型的字段。所以就像你有这个代码一样:
class Author {
Set<Book> books
static hasMany = [books: Book]
String name
}
和
class Book {
Author author
static belongsTo = [author: Author]
String title
}
AST xform使用map键作为字段名称,因此您可以使用任何有效的字段名称,但惯例是执行您所做的操作。
默认情况下,属性为nullable:false
,因此您的代码不会保存Book
实例,因为您未设置author
属性。明确地执行此操作时,通常不会直接创建Book
,而是使用动态Author
方法将其添加到addToBooks
的集合中。这将设置author
字段返回引用,当您保存作者时,将对该书进行传递验证并保存。当您拥有new Book(params).save()
之类的代码时,这一切都会为您处理,您可以直接执行此操作,例如。
Author author = ...
def book = new Book(title:"New Grails Book", author: author).save()
如果您使用的是生成的控制器和GSP,params
地图中应该有作者ID,它可能是author.id
,因此第一行将是
Author author = Author.get(params['author.id'])
但你可以添加
println params
在操作方法的顶部,查看所有提交的参数。
通常,您不希望查看保存调用的返回值,因为如果存在验证错误并且无法检索错误,则它将为null。所以改变
def book = new Book(...).save()
到
def book = new Book(...)
book.save()
现在您可以拨打book.hasErrors()
,book.getErrors()
,book.errors
等来查看是否成功,如果没有,则会出现问题。
但这不是你所看到的确切问题,只是你解决问题时的问题。没有save.gsp
,Grails也会查找save.jsp
,并且在未找到的消息中容易混淆该名称。 save
方法通过POST请求访问,通常来自create
操作生成的表单,并且在验证失败时重新显示create.gsp
提交的数据和错误消息,或者在保存成功时重定向到view
操作。使用生成的代码时无需save.gsp
。