Search code examples
grailsgroovygrails-controller

Updating many item using same id in grails


I am saving values in two tables asset and asset_history.On creating asset i am saving values in asset table if any update i wantthat time it as to store in asset and asset_history on id bases . Now i want to get two tables value in edit page for getting asset_history i used sql query to get values in asset_history.all are working well and fine but it is coming in array list values(all update list is showing in single row).when i updata values in edit page it should save and show in different rows in asset_history. for that i used for loop but it not getting values.

asset table i have these fields :-

     id
      asset_title
      asset_description
      client_id
      comment
      status
etc...

In asset_history field:-

id
comment
update_on
update_by
status

If any update in asset field.The update list should save in both asset and asset_history.I have used a query to update(as shown below). But it is getting arraylist in asset_history table.

edit action

    def dataSource
def edit={
    def assetInstance = Asset.get(params.id)
        if (!assetInstance) { 

            flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'asset.label', default: 'Asset'), params.id])}"
            redirect(action: "list")
        }
        else {  Sql sql = new Sql(dataSource) 
             def result = sql.rows("SELECT * from asset_history where id ='"+params.id+"' ")
            //def n=result

            /*  def arr = (String[])result
                        for(i in 0 .. result.size()-1)
                         {

            return [assetInstance: assetInstance,result:i]
                         }*/
                   return [assetInstance: assetInstance,result: result]
        }

    }

In edit.gsp

<tbody>

                        <tr>


                          <td>${result.id}</br></td>
                            <td>${result.comment}</br></td>

                            <td>${result.update_on}</br></td>
                           <td>${result.update_time}</br></td>
                               <td>${result.update_by}</br></td>

                        </tr>

                    </tbody>

In asset_history table the values are getting in arraylist and showing updated list in single row.But i want show it in separate row ,when i update each time.I used for-loop for this but it is not working.Please guide me to solve this problem.


Solution

  • Your problem is that you can only return one value from a function in Groovy (and in all other languages I know anyway). So the first iteration in your for loop returns and the following iterations (where you expect to return more instances) are not executed.

    You must return a list and use a <g:each> tag in your GSP file (which is the equivalent to a for loop in GSP):

    def edit = {
      def assetInstance = Asset.get(params.id)
      if (!assetInstance) {
        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'asset.label', default: 'Asset'), params.id])}"
        redirect(action: "list")
      }
      Sql sql = new Sql(dataSource) 
      def results = sql.rows("SELECT * from asset_history where id ='" + params.id + "' ")
      return [results: results]
    }
    

    And your GSP:

    <tbody>
      <g:each var="result" in="${result}">
        <tr>
          <td>${result.id}</br></td>
          <td>${result.comment}</br></td>
    
          <td>${result.update_on}</br></td>
          <td>${result.update_time}</br></td>
          <td>${result.update_by}</br></td>
        </tr>
      </g:each>
    </tbody>
    

    As a bonus, here are a few tips that will make your application look better:

    • Don't return values if you don't use them in your GSP, like assertInstance here
    • Avoid using SQL and prefer relying on Grails built-in access methods (findBy) or Hibernate Criteria if your assert history are Grails domain objects. This will give you Grails objects backs instead of raw SQL rows
    • Indent your code correctly for readability. Chances are that your IDE have a feature that can do that for you.