首页 > 解决方案 > 不刷新的 save() 不保存记录?

问题描述

我正在玩 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() 不保存记录?我错过了什么吗?感谢帮助!

完整代码:

首先创建一个域Book如下

class Book {
    String name
    static constraints = {
    }
}

创建图书控制器

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')
    }
}

意见

创建.gsp

<h1> Create Book Page</h1>

<g:form action="save">

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

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

</g:form>

编辑.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>

索引.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>

显示.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()。需要添加保存(刷新:真)。谢谢!

更新: 这很奇怪。相同的代码适用于 grails 2。我尝试使用 grails 2.2。它只是不适用于 grails 3。我用来测试的 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>

当我单击删除时,它会重定向到索引页面,但我仍然可以看到记录。我错过了什么吗?谢谢!

标签: grails

解决方案


我在我曾经开发过的每个 Grails 应用程序中都看到了两个经典错误。所以不要气馁。

首先,虽然您可以在控制器中进行持久性,但您不应该将服务与您的业务逻辑与路由和渲染分离。

其次,当您进行数据库修改时,您应该使用事务。在 Grails 中,您可以使用 @Transactional 来做到这一点,您可以将其添加到方法或类中。一般来说,您不必执行flush:true,除非您需要已保存记录的ID。@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()
    }

推荐阅读