save()不刷新不保存记录吗?

时间:2018-07-15 05:25:55

标签: grails

我正在玩grails 3应用。我使用粗体动作创建了这个简单的书本应用程序。它不更新记录。

这是书域

package bookapp

class Book {

    String name

    static constraints = {
    }
}

这是图书管理员

package bookapp

import grails.plugin.springsecurity.annotation.Secured

@Secured('ROLE_USER')
class BookController {

    def index() {

        [books: Book.findAll()]
    }

    def create(){

    }

    def save(){
        def book = new Book(params)
        book.save()

        redirect(action:'show', id:book.id)
    }

    def edit(Long id){
        [book: Book.get(id)]
    }

    def update(Long id){

        def book = Book.get(id)

        bindData(book, params)

        book.save()

        redirect(action:'show', id:book.id)

    }

    def show(Long id){
        [book: Book.get(id)]
    }

    def destroy(){

    }
}

这是编辑视图页面

<h1> Edit Book Page</h1>

<g:form action="update" id="${book.id}">

    <g:textField name="name" value="${book.name}"></g:textField>

    <g:submitButton name="submit"></g:submitButton>

</g:form>

当我进入编辑页面并更改名称字段,然后单击提交按钮。它不会更新这本书。如果我将更新操作更改为

 def update(Long id){

            def book = Book.get(id)

            bindData(book, params)

            book.save(flush:true)

            redirect(action:'show', id:book.id)

        }

这有效。所以我的问题是为什么我们需要显式刷新?为什么save()不保存记录?我有什么想念的吗?感谢您的帮助!

完整代码:

首先按如下方式创建域图书

class Book {
    String name
    static constraints = {
    }
}

创建Book控制器

class BookController {

    def index() {

        [books: Book.findAll()]
    }

    def create(){

    }

    def save(){
        def book = new Book(params)
        book.save()
        redirect(action:'show', id:book.id)
    }

    def edit(Long id){
        [book: Book.get(id)]
    }

    def update(Long id){
        def book = Book.get(id)
        book.properties = params
        book.save()
        redirect(action:'show', id:book.id)
    }

    def show(Long id){
        [book: Book.get(id)]
    }

    def destroy(Long id){
        Book.get(id).delete()
        redirect(action:'index')
    }
}

观看次数

create.gsp

<h1> Create Book Page</h1>

<g:form action="save">

    <g:textField name="name"></g:textField>

    <g:submitButton name="submit"></g:submitButton>

</g:form>

edit.gsp

<h1> Edit Book Page</h1>

<g:form action="update" id="${book.id}">

    <g:textField name="name" value="${book.name}"></g:textField>

    <g:submitButton name="submit"></g:submitButton>

</g:form>

index.gsp

<g:each in="${books}" var="book">

    <h2><g:link action="show" id="${book.id}"> ${book.name} </g:link></h2>

</g:each>


<g:link controller="book" action="create">Create Book</g:link>

show.gsp

<h1> ${book.name} </h1>

<g:link action="edit" id="${book.id}">Edit</g:link>
<g:link action="destroy" id="${book.id}">Delete</g:link>
<g:link action="index">Back</g:link>

删除和更新不适用于仅save()。需要添加save(flush:true)。谢谢!

更新: 这很奇怪。相同的代码适用于grails2。我尝试过grails 2.2。它仅不适用于grails3。我用来测试的grails 3版本是grails 3.3.6。 grails 3是否有任何改变打破了这一点?

更新2:

我现在将删除操作移至服务中,如下所示。

@Transactional
class BookService {

    def destroy(Long id) {

        def b = Book.get(id)
        b.delete()

    }
}

在控制器中

class BookController {

    def bookService

    def destroy(Long id){
        bookService.destroy(id)
        redirect(action:'index')
    }
}

要删除的查看代码是

<h1> ${book.name} </h1>

<g:link action="edit" id="${book.id}">Edit</g:link>
<g:link action="destroy" id="${book.id}">Delete</g:link>
<g:link action="index">Back</g:link>

当我单击“删除”时,它将重定向到索引页面,但我仍然可以看到记录。我有什么想念的吗?谢谢!

1 个答案:

答案 0 :(得分:4)

在我曾经使用过的每个Grails应用程序中,我都看到了两个经典错误。因此,不要灰心。

首先,虽然您可以在Controller中进行持久性处理,但您不应该将其用于服务,以使业务逻辑与路由和呈现脱钩。

第二,当您进行数据库修改时,您应该使用事务。在Grails中,您可以使用@Transactional来实现,可以将其添加到方法或类中。通常,除非需要保存的记录的ID,否则不必执行flush:true。 @Transactional可以采用许多参数来更改事务的工作方式: https://docs.grails.org/latest/guide/services.html#declarativeTransactions

前一段时间,我为Grails 3创建了这些架构图: https://github.com/virtualdogbert/Grails_Architecture

我还创建了此页面作为Groovy / Grails资源的位置: https://github.com/virtualdogbert/Groovy_Links

希望有帮助。

对于删除而言,您在服务中的列表设置如下:

class BookService {

    @Transactional(readOnly = true)
    def listBooks() {
        Book.list()
    }