Search code examples
grails

Preventing a write to the database from Grails controller


I have a small Grails project I'm writing as a learning exercise. It gathers some user input from a form (eg. enter two numbers to add), then it calls a service to process that data (eg. add the two numbers), and finally it shows the results on a another page.

When I turned on SQL logging I noticed that the data the user is entering is being saved to the database before the call to the service method inside the controller.

How do I prevent this? I would like ONE write to the database after the call to the service method is complete and there are no errors.

Save method from controller code:

 def save() {
      def myInstance = new myDomainClass(params)
      myInstance.sessionId = session.id
      myService argh = new myService()

      // wtf does this do?
      if (!myInstance.save(flush: true)) {
           render(view: "create", model: [myInstance: myInstance])
           return
       }

       // Execute the api and process the results. what is writing the user input to the database before this call?!?!?!?!

       def results1 = argh.executeApi(myInstance)

      // if the results are null throw an error
      if (results1 == null) {
          flash.message = message(code: 'api.null.error')
          render(view: "create", model: [apiInstance: apiInstance])
          return
      } else {
          forward(action: "list", id: 2, model: [apiInstanceList: Api.list(params), apiInstanceTotal: Api.count()])
      }
 }

Pointers or help appreciated.


Solution

  • Calling .save(flush:true) will automatically save the myInstance instance to the database at that point. You will want to move the .save(flush:true) to after the service method, and since you said you wanted to make sure there were no errors, you would want to add it to your conditional:

    def save() {
          def myInstance = new myDomainClass(params)
          myInstance.sessionId = session.id
          myService argh = new myService()
    
           // Execute the api and process the results. what is writing the user input to the database before this call?!?!?!?!
    
           def results1 = argh.executeApi(myInstance)
    
          // if the results are null throw an error
          if (results1 == null) {
              flash.message = message(code: 'api.null.error')
              render(view: "create", model: [apiInstance: apiInstance])
              return
          } else {
               // save here when you know there are no errors
               if (!myInstance.save(flush: true)) {
                   render(view: "create", model: [myInstance: myInstance])
                   return
               }
              forward(action: "list", id: 2, model: [apiInstanceList: Api.list(params), apiInstanceTotal: Api.count()])
          }
     }