StartingGroovy
StartingGroovy

Reputation: 2860

Grails Controllers adding instances

Alright I asked a question before but wasn't quite sure about it. So I went ahead and waited till now to ask again.

Main Question

How do I add a new instance of the domain through the controller? I created a function named gather to read a file with data and then create a new Book with the specific information, however it is not adding it to the database at all.

I currently have a controller (bookController) and the domain for it.

My domain is quite simple:

class Book {

    static belongsTo = Author

    String toString() { bookNumber }

    Author bookAuthor
    String title


    static constraints = {
        bookAuthor()
        title()

    }
}

I just 'generated' my views so I have the basic create, edit, list, and show. I went ahead and added my own inside the controller called gather. For the gsp, I just copied over the 'list.gsp' as I just want the user to view the list of books once the gather function is completed.

Here is what my controller looks like (just the basic generated one plus gather):

package bookdemo

import bookClient

class BookController {

    static allowedMethods = [save: "POST", update: "POST", delete: "POST"]

    def index = {
        redirect(action: "list", params: params)
    }

    def gather = {

        def w = new bookClient()        //bookClient will gather books from txt files
        def hosts = ["localhost"]       //host to connect to

        w.queryData(hosts)          //grab information and parse
        def abc = w.bookList            //list of books
        w.printData(abc)            //print out list of books to make sure its not null

        int numberOfBooks = abc.size()  //list size


    //create book list and return it

        numberOfBooks.times {
        def bookInstance = new Book(Author:"$abc.author", Title:"$abc.title")
            return [bookInstance: bookInstance]
        }


    //params to show once adding books

        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [bookInstanceList: book.list(params), bookInstanceTotal: book.count()]
    }

    def list = {
        params.max = Math.min(params.max ? params.int('max') : 10, 100)
        [bookInstanceList: book.list(params), bookInstanceTotal: book.count()]
    }

    def create = {
        def bookInstance = new Book()
        bookInstance.properties = params
        return [bookInstance: bookInstance]
    }

    def save = {
        def bookInstance = new Book(params)
        if (bookInstance.save(flush: true)) {
            flash.message = "${message(code: 'default.created.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id])}"
            redirect(action: "show", id: bookInstance.id)
        }
        else {
            render(view: "create", model: [bookInstance: bookInstance])
        }
    }

    def show = {
        def bookInstance = book.get(params.id)
        if (!bookInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
            redirect(action: "list")
        }
        else {
            [bookInstance: bookInstance]
        }
    }

    def edit = {
        def bookInstance = book.get(params.id)
        if (!bookInstance) {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
            redirect(action: "list")
        }
        else {
            return [bookInstance: bookInstance]
        }
    }

    def update = {
        def bookInstance = book.get(params.id)
        if (bookInstance) {
            if (params.version) {
                def version = params.version.toLong()
                if (bookInstance.version > version) {

                    bookInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [message(code: 'book.label', default: 'Book')] as Object[], "Another user has updated this Book while you were editing")
                    render(view: "edit", model: [bookInstance: bookInstance])
                    return
                }
            }
             bookInstance.properties = params
            if (!bookInstance.hasErrors() && bookInstance.save(flush: true)) {
                flash.message = "${message(code: 'default.updated.message', args: [message(code: 'book.label', default: 'Book'), bookInstance.id])}"
                redirect(action: "show", id: bookInstance.id)
            }
            else {
                render(view: "edit", model: [bookInstance: bookInstance])
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
            redirect(action: "list")
        }
    }

    def delete = {
        def bookInstance = book.get(params.id)
        if (bookInstance) {
            try {
                bookInstance.delete(flush: true)
                flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
                redirect(action: "list")
            }
            catch (org.springframework.dao.DataIntegrityViolationException e) {
                flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
                redirect(action: "show", id: params.id)
            }
        }
        else {
            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'book.label', default: 'Book'), params.id])}"
            redirect(action: "list")
        }
    }
}

The gsp shows up but for some reason my new books are not added. When I add a println in to test whether the information is in the list, it shows prints with the correct info. So I'm confused as to why it is not 'creating' the new book instance and adding it to the database.

Any suggestions?

Edit

Domain class for author:

class Author {

    static hasMany = [books:Book]

    String authorName
    String notes

    String toString() { authorName }


    static constraints = {
        machineName()
        notes(maxSize:500)
    }
}

Upvotes: 0

Views: 4238

Answers (2)

leebutts
leebutts

Reputation: 4882

You're not calling .save() on any of the Book instances...

Upvotes: 2

Aaron Saunders
Aaron Saunders

Reputation: 33335

I would suggets you write some unit tests for you controller and/or domain objects. Your objects cannot be being created successfully with this code

new Book(Author:"$abc.author", Title:"$abc.title")

Also the return statement here makes no sense

    numberOfBooks.times {
    def bookInstance = new Book(Author:"$abc.author", Title:"$abc.title")
        return [bookInstance: bookInstance]
    }

It looks like you have cut and pasted code without understanding what the code is doing. I think you want something more like this...

    // iterate through the list of books and create the object array to pass back
    def bookListInstance = []
    w.bookList.each {
        def bookInstance = new Book(Author:it.author, Title:it.title)
        bookListInstance << bookInstance
    }
    // now return the list of domain objects
    return [bookInstance: bookListInstance]

Upvotes: 2

Related Questions