views:

50

answers:

1

As I'm a bit new to grails, I'm wondering how I can iterate through the current data i have saved in the database to check if the information already exists.

For instance, lets say I have a domain class for Books and I create an action that automatically adds more books but I want to check if the book.title already exists so I don't add it again.

Side note I'm just using the default database (whatever is used when the project is set to production mode)


Edit

I'll post my domains so it is a bit easier to understand. Instead of book.title, I changed it to where book belongs to author. So I only want the author added once but able to add many books for it. The issue happens in an action i created in the controller.

Author Domain:

class Author {

    static hasMany = [books:Book]

    String authorName
    String notes
    String age

    String toString() { authorName }


    static constraints = {
        authorName()
        notes(maxSize:500)
        age()
    }
} 

Book Domain:

class Book {

    static belongsTo = Author

    String toString() { bookNumber }

    Author bookAuthor
    String title
    String numberOfPages


    static constraints = {
        bookAuthor()
        title()
        numberOfPages()
    }
}

Book Controller (this is where I'm having issues):

class BookController {

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

    //took out index, create, list, etc. to focus on the once that I'm concerned about


    //this action will simple read a text file and add books and authors
    def gather = {

        def parseData = new parseClient()        //parses text file line by line and puts it into a list  
        def dataHolder = parseData.information   //dataHolder will hold data from text file

        int linesOfData = dataHolder.size()      //get size to iterate and add authors & books

        linesOfData.times {
            def _author = dataHolder.author[it]  //get author - Author
            def _age = dataHolder.age[it]        //get age    - Author

            def _title = dataHolder.title[it]    //get title - Book
            def _pages = dataHolder.pages[it]    //get pages - Book

            def authorInstance                   //create new Author to add
            authorInstance = new Author()        //for some reason I have to create and save AuthorName (can't have other fields) before I can add my Book correctly
            authorInstance.setAuthorName(_author)
            authorInstance.save()

            def bookInstance
            bookInstance = new Book()           //create a new Book to add
            bookInstance.setBookAuthor(authorInstance)
            bookInstance.setTitle(_title)
            bookInstance.setNumberOfPages(_pages)
            bookInstance.save()                 //has to have access to the authorInstance to add correctly which is why i was wondering how to access the database to grab it if it existed

            authorInstance.setAge(_age)        //add whatever data is left for Author
            authorInstance.save()              //save again because cant save it with this information before I add authorInstance to the Book
        }

    }

}

Text File Content:

//You'll notice that author _Scott Davis_ is in here twice.
//I don't want to add two instances of Scott Davis but need to access it to add the book
//the unique constraint makes the value come up as not null but can't be added 

Scott Davis : Groovy Recipes
Bashar Abdul Jawad : Groovy and Grails Recipes
Fergal Dearle : Groovy for Domain-Specific Languages
Scott Davis : GIS for Web Developers: Adding 'Where' to Your Web Applications

So I'm basically looking for a way to add that information and haven't found a way that seems to work without running into random problems.

Hope this clears my question up a bit, as the original question was a bit broad

+2  A: 

In this case, you can put a unique constraint on title and grails will do that for you.

You can iterate thru the data, but you probably don't want to load the db if you can avoid it. So you could write a custom query to select the number of books for the title, for example.

Edit: for your updates

  1. You don't need to use setters in your controller. Grails adds setters/getters for you dynamically at runtime. If you want to put some logic in your setters, then you can define your own and use them in that case

  2. Have you looked at the grails documentation? http://grails.org/doc/latest/

you have a static constraints block, but you haven't defined how you want each property to be constrained. for unique title it would be

 title(unique:true)

if you want to get a list of author names, you can do

List names = Author.executeQuery('select authorName from Author')
hvgotcodes
Thank you for the help hvgotcodes, the unique constraint would work, but i realized that I'm having issues adding it in. I'll edit my original post shortly with the updated issue.
StartingGroovy
Just thought I would let you know I updated the main post with the more specific question.
StartingGroovy
1. Perhaps I understand your number 1 incorrectly, but it works fine when opening up the website and creating the Author or Book manually. The setters I have are for when I read a file and want to push the information from the file directly in without having to type each one in. I had to split authorInstance in half because the bookInstance won't create if there is other parts of info in it.
StartingGroovy
2. I removed the constraints but left those in the static constraints box so that they would show up in that order. When using unique:true it gives me the issue when adding the new Book.
StartingGroovy
I think what I'm trying to ask is, is there a way to grab the AuthorName from the Author table to check if it matches my String that I'm reading in from the text file? That way I'm able to use that for adding my new Book? (Essentially something that would be the same as selecting an Author from the drop menu when manually adding it) Would I use findByAuthorName? --- by the way, thank you for the prompt response, it's appreciated
StartingGroovy
@startinggroovy - why dont you make authorName unique?
hvgotcodes
Well when I do have authorName(unique:true) and attempt to add a new Book with the same authorName as one before, I get the following: _caused exception: not-null property references a null or transient value_ Which is why I am wanting to check the Author table if it exists. If it does exist, I would like to use that Author value for the new Book entry. So if I do an executeQuery and it exists, how do I use that value? (Excuse me for so many questions, this is my first time dealing with databases)
StartingGroovy
Thank you for all the help, I learned quite a bit from what you have posted. For now, I think Author.findByAuthorName('authorsName') will work just fine :)
StartingGroovy