2011-03-15 7 views
6

मैं कई-बहुत से रिश्ते वाले वस्तुओं को बचाने की कोशिश कर रहा हूं। एक सेलिंग कॉम्पनी में कई खाते हो सकते हैं और कई सेलिंग कंपनियों के साथ एक खाता जोड़ा जा सकता है। तो SellingCompaniesAccount में संग्रहीत तालिकाओं के बीच अनेक-अनेक संबंध हैअंगों में कई से अधिक रिश्ते रखने वाली वस्तु को सहेजना

मेरे ACCOUNT_INFO डोमेन इस प्रकार है:

class SellingCompanies 
{ 

    static mapping = { 
     table 'SellingCompanies' 
     version false 
    } 

    String name 

    //static belongsTo = AccountInfo 

    //static hasMany = [accounts: AccountInfo] 
    static hasMany = [sellingcompaniesaccount:SellingCompaniesAccount] 

    static constraints = { 

    name(blank:false, validator: 
     { val, obj -> 
      def similarSellingCompanies = SellingCompanies.findByNameIlike(val) 
      return !similarSellingCompanies || (obj.id == similarSellingCompanies.id) 
     }) 
    } 

    //String toString() { name } 
} 

तालिका रखती है:

class AccountInfo { 
    static mapping ={ 
     table 'AccountInfo' 
     version false 
     //id column:'accountInfoID' 
    } 

    String evi_pass_phrase 
    String evi_username 
    String security_key 

    // to make sure fields show up in a particular order 

    static constraints = { 
     //accountInfoID(insert:false,update:false) 
     evi_pass_phrase() 
     evi_username() 
     security_key() 

    } 

    static hasMany = [sellingcompaniesaccount:SellingCompaniesAccount] 


    String toString() { 
     return "${evi_username}" 
    } 
} 

मेरे SellingComapanies डोमेन इस प्रकार है कई-रिश्ते निम्नानुसार हैं:

class SellingCompaniesAccount { 

    static constraints = { 
     // ensure the group of sellingCompaneis and accountInfo values are unique 
     agency_name(unique:['sellingCompanies','accountInfo']) 
    } 

    int agency_id 
    String agency_name 
    String consultant_id 
    String code 
    Boolean isActive 
    String iata 

    ContactInfo contactinfo 

    static belongsTo = [sellingCompanies:SellingCompanies, accountInfo:AccountInfo] 

     } 

} 

create.gsp फ़ाइल में प्रपत्र में वह कोड होता है जो वास्तव में सभी अलग-अलग सेलिंग कंपनियों पर प्रदर्शित होता है और चेक-बॉक्स के रूप में प्रदर्शित होता है।

<g:form action="save" method="post"> 
    <div class="dialog"> 
    <table width="500px" border="0px" color="red"> 
     <tbody> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="accountInfo"><g:message 
        code="sellingCompaniesAccount.accountInfo.label" 
        default="Account Info" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'accountInfo', 'errors')}"> 
       <g:select name="accountInfo.id" 
        from="${content_hub_admin.AccountInfo.list()}" optionKey="id" 
        value="${sellingCompaniesAccountInstance?.accountInfo?.id}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="sellingCompanies"><g:message 
        code="sellingCompaniesAccount.sellingCompanies.label" 
        default="Selling Companies" /></label></td> 
       <td valign="top" 
        class=""> 
        <g:each in="${content_hub_admin.SellingCompanies.list()}" var="item" status="i"> 
         ${++i}. ${item.name}&nbsp;&nbsp;<g:checkBox name="sellingcompanies_${++i-1}" optionKey="id" value="${item.id}" /> <br> 
        </g:each> 
       <!-- end here by rsheyeah --> 
       </td> 
      </tr> 



      <tr class="prop"> 
       <td valign="top" class="name"><label for="code"><g:message 
        code="sellingCompaniesAccount.code.label" default="Code" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'code', 'errors')}"> 
       <g:textField name="code" 
        value="${sellingCompaniesAccountInstance?.code}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="agency_name"><g:message 
        code="sellingCompaniesAccount.agency_name.label" 
        default="Agencyname" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'agency_name', 'errors')}"> 
       <g:textField name="agency_name" 
        value="${sellingCompaniesAccountInstance?.agency_name}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="isActive"><g:message 
        code="sellingCompaniesAccount.isActive.label" default="Is Active" /></label> 
       </td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'isActive', 'errors')}"> 
       <g:checkBox name="isActive" 
        value="${sellingCompaniesAccountInstance?.isActive}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="agency_id"><g:message 
        code="sellingCompaniesAccount.agency_id.label" default="Agencyid" /></label> 
       </td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'agency_id', 'errors')}"> 
       <g:textField name="agency_id" 
        value="${fieldValue(bean: sellingCompaniesAccountInstance, field: 'agency_id')}" /> 
       </td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="iata"><g:message 
        code="sellingCompaniesAccount.iata.label" default="Iata" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'iata', 'errors')}"> 
       <g:textField name="iata" 
        value="${sellingCompaniesAccountInstance?.iata}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="consultant_id"><g:message 
        code="sellingCompaniesAccount.consultant_id.label" 
        default="Consultantid" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'consultant_id', 'errors')}"> 
       <g:textField name="consultant_id" 
        value="${sellingCompaniesAccountInstance?.consultant_id}" /></td> 
      </tr> 

      <tr class="prop"> 
       <td valign="top" class="name"><label for="contactinfo"><g:message 
        code="sellingCompaniesAccount.contactinfo.label" 
        default="Contactinfo" /></label></td> 
       <td valign="top" 
        class="value ${hasErrors(bean: sellingCompaniesAccountInstance, field: 'contactinfo', 'errors')}"> 
       <g:select name="contactinfo.id" 
        from="${content_hub_admin.ContactInfo.list()}" optionKey="id" 
        value="${sellingCompaniesAccountInstance?.contactinfo?.id}" /></td> 
      </tr> 

     </tbody> 
    </table> 
    </div> 
    <div class="buttons"><span class="button"><g:submitButton 
     name="create" class="save" 
     value="${message(code: 'default.button.create.label', default: 'Create')}" /></span> 
    </div> 
</g:form> 

अंततः नियंत्रक जो सहेजने और सूची कार्यों को संभालता है।

class SellingCompaniesAccountController { 

    private static Logger log = Logger.getLogger(SellingCompaniesAccountController.class) 

    //def index = { } 
    //def scaffold = true 

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

    //To limit access to controller actions based on the HTTP request method. 
    def allowedMethods = [save:'POST'] 

    //create.gsp exists 
    def create = { 
     render(view:"create") 
    } 

    //edit.gsp exists 
    //def edit = {} 

    //list.gsp exists 
    def list = { 
     [ sellingCompaniesAccountInstanceList: SellingCompaniesAccount.list(max:15) ] 
     } 

    //show.gsp exists 
    //def show={} 

    //save.gsp exists 
    def save = { 
     log.info "Saving: " + params.toString() 

     println("Saving: " + params.toString()) 
     def sellingCompaniesAccount = params.sellingCompaniesAccount 
     println(sellingCompaniesAccount) 

     def sellingCompanies = params.sellingCompanies 

     log.info "sellingCompanies: " + sellingCompanies 
     println(sellingCompanies) 


     def sellingCompaniesAccountInstance = new SellingCompaniesAccount(name: params.name) 

     println(params.name) 

     params.each { 
      if (it.key.contains("_sellingcompanies")) 
      //sellingCompaniesAccountInstance.sellingCompaniesId << SellingCompanies.get((it.key - "sellingcompanies_") as Integer) 
      if (it.key.contains("sellingcompanies_")) 
       sellingCompaniesAccountInstance.sellingCompaniesId << SellingCompanies.get((it.key - "sellingcompanies_") as Integer) 
     } 
     log.info sellingCompaniesAccountInstance 
     if (sellingCompaniesAccountInstance.save(flush: true)) { 
      flash.message = "${message(code: 'default.created.message', args: [message(code: 'sellingCompaniesAccountInstance.label', default: 'sellingCompaniesAccountInstance'), sellingCompaniesAccountInstance.id])}" 
      redirect(action: "show", id: sellingCompaniesAccountInstance.id) 
      log.info sellingCompaniesAccountInstance 
     } 
     else { 
      render(view: "create", model: [sellingCompaniesAccountInstance: sellingCompaniesAccountInstance]) 
     } 


    } 

} 

अब, मैं निम्न त्रुटि हो रही है, कारण खाली छिपा मूल्यों _sellingcompanies_1 आदि .:

त्रुटि लॉग्स की तरह दिखाई दे रहा है:

Saving: ["accountInfo.id":"1", "accountInfo":["id":"1"], "_sellingcompanies_5":"", "_isActive":"", "code":"test", "agency_name":"test", "sellingcompanies_4":"4", "sellingcompanies_5":"5", "create":"Create", "isActive":"on", "iata":"test", "agency_id":"test", "contactinfo.id":"1", "contactinfo":["id":"1"], "consultant_id":"test", "sellingcompanies_2":"2", "_sellingcompanies_1":"", "sellingcompanies_3":"3", "_sellingcompanies_2":"", "_sellingcompanies_3":"", "sellingcompanies_1":"1", "_sellingcompanies_4":"", "action":"save", "controller":"sellingCompaniesAccount"] 
null 
null 
null 
2011-03-15 17:13:44,620 [http-8080-2] ERROR org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver - For input string: "_5" 
java.lang.NumberFormatException: For input string: "_5" 
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48) 
    at java.lang.Integer.parseInt(Integer.java:449) 
    at java.lang.Integer.valueOf(Integer.java:554) 
    at content_hub_admin.SellingCompaniesAccountController$_closure4_closure5.doCall(content_hub_admin.SellingCompaniesAccountController:70) 
    at content_hub_admin.SellingCompaniesAccountController$_closure4.doCall(content_hub_admin.SellingCompaniesAccountController:66) 
    at content_hub_admin.SellingCompaniesAccountController$_closure4.doCall(content_hub_admin.SellingCompaniesAccountController) 
    at java.lang.Thread.run(Thread.java:680) 

सबसे पहले, जहां छिपा हुआ है मूल्यों से आते हैं और यह दृष्टिकोण SellingCompaniesAccount नियंत्रक वर्ग में कई-कई रिश्ते की जानकारी को करने के लिए ठीक है। ऐसा करने की कोई बेहतर तकनीक।

create.gsp ब्राउज़र में इस पर ले कर जाता: enter image description here

अग्रिम धन्यवाद

+1

आपको प्रासंगिक कोड को प्रतिबंधित करना चाहिए, यह अन्य पढ़ने को और अधिक आसान बनाने में आपकी सहायता करता है और आपकी समस्या को समझता है। –

+0

लॉग पॉइंट के रूप में, यह एक डेटा-प्रकार त्रुटि है। क्या आपने SellingCompaniesAccountController लाइन 70 को देखा है? –

+0

धन्यवाद होआंग लांग, जांच के बाद, मैंने पाया कि चेकबॉक्स एक छिपे हुए क्षेत्र को प्रस्तुत करता है। मैं इस छिपे हुए क्षेत्र को कैसे अक्षम कर सकता हूं? कोई विचार। और मैं चुने गए प्रत्येक चेकबॉक्स के लिए SellingCompaniesAccount तालिका में एक रिकॉर्ड कैसे जोड़ सकता हूं। –

उत्तर

1

समस्या कोड के इस टुकड़े के साथ है:

params.each { 
     if (it.key.contains("_sellingcompanies")) 
     //sellingCompaniesAccountInstance.sellingCompaniesId << SellingCompanies.get((it.key - "sellingcompanies_") as Integer) 
     if (it.key.contains("sellingcompanies_")) 
      sellingCompaniesAccountInstance.sellingCompaniesId << SellingCompanies.get((it.key - "sellingcompanies_") as Integer) 
    } 

आपका प्रपत्र पद से पैरामीटर हैं:

Saving: ["accountInfo.id":"1", "accountInfo":["id":"1"], "_sellingcompanies_5":"", "_isActive":"", "code":"test", "agency_name":"test", "sellingcompanies_4":"4", "sellingcompanies_5":"5", "create":"Create", "isActive":"on", "iata":"test", "agency_id":"test", "contactinfo.id":"1", "contactinfo":["id":"1"], "consultant_id":"test", "sellingcompanies_2":"2", "_sellingcompanies_1":"", "sellingcompanies_3":"3", "_sellingcompanies_2":"", "_sellingcompanies_3":"", "sellingcompanies_1":"1", "_sellingcompanies_4":"", "action":"save", "controller":"sellingCompaniesAccount"] 

आपके लूप में परीक्षण पहले जांचता है कि पैरामीटर कुंजी में "_बिकने वाली कंपनियां" और फिर यह कुछ भी नहीं करता है; उस जांच का दूसरा भाग यदि पैरामीटर कुंजी में "बिकने वाली कंपनियां _" शामिल हैं और फिर यह उस पैरामीटर मान से प्रत्यय संख्या को खींचने का प्रयास करता है। कुंजी मान "_sellingcompanies_5" वाले पैरामीटर के मामले में, पहले परीक्षण और दूसरा परीक्षण दोनों सत्य का मूल्यांकन करते हैं, इसलिए दूसरे परीक्षण में, आप पैरामीटर कुंजी मान से "विक्रय कंपनियां _" घटा रहे हैं और आप "_5" के साथ छोड़े गए हैं, जिन्हें आप एक इंटीजर का मूल्यांकन करने की कोशिश कर रहे हैं। दुर्भाग्यवश, "_5" मान्य पूर्णांक मान नहीं है, और इसलिए आपकी दी गई त्रुटि है।

आप निम्न कार्य करके बहुत आसानी से इस का समाधान कर सकते हैं:

params.each { 
    if (it.key.startsWith("sellingcompanies")) { 
     sellingCompaniesAccountInstance.sellingCompaniesId << SellingCompanies.get((it.key - "sellingcompanies_") as Integer) 
    } 
} 

शायद एक बेहतर हालांकि इस संभाल करने के लिए अपने जीएसपी बदलने के लिए sellingcompanies से प्रत्येक के लिए एक ही नामित पैरामीटर देने के लिए किया जाएगा जिस तरह से, और उसके बाद वास्तविक लागू मूल्यों के माध्यम से लूपिंग। कुछ इस तरह:

 <!-- ... snip ... --> 
     <tr class="prop"> 
      <td valign="top" class="name"><label for="sellingCompanies"><g:message 
       code="sellingCompaniesAccount.sellingCompanies.label" 
       default="Selling Companies" /></label></td> 
      <td valign="top" 
       class=""> 
       <g:each in="${content_hub_admin.SellingCompanies.list()}" var="item" status="i"> 
        ${++i}. ${item.name}&nbsp;&nbsp;<g:checkBox name="sellingcompanies" optionKey="id" value="${item.id}" /> <br> 
       </g:each> 
      <!-- end here by rsheyeah --> 
      </td> 
     </tr> 
     <!-- ... snip ... --> 
फिर अपने नियंत्रक में

कुछ इस तरह करते हैं:

params.sellingcompanies = [params.sellingcompanies].flatten() as String[] 

sellingCompaniesAccountInstance.sellingCompaniesId = params.sellingcompanies.collect { SellingCompanies.get(it) } 

यह सुनिश्चित करना चाहिए कि आप ठीक ढंग से उचित मान अपने मॉडल वस्तु से पारित कर दिया गया है मूल्यांकन कर रहे हैं, और हैकिंग नहीं एक पुनर्प्राप्ति विधि में।

आशा है कि इससे मदद मिलती है!

2

अगर किसी और एक ही समस्या हो रही है किसी को भी तो डेनियल ने इसके बाद के संस्करण जवाब बिल्कुल सही है बस Grails के रूप में कुछ परिवर्तन 2.7.8

सभी चेकबॉक्स एक ही मूल्य है जाएगा जोड़ने = "$ {item.id}" और नाम = "sellingcompanies" below-

<!-- ... snip ... --> 
    <tr class="prop"> 
     <td valign="top" class="name"><label for="sellingCompanies"><g:message 
      code="sellingCompaniesAccount.sellingCompanies.label" 
      default="Selling Companies" /></label></td> 
     <td valign="top" 
      class=""> 
      <g:each in="${content_hub_admin.SellingCompanies.list()}" var="item" status="i"> 
       ${++i}. ${item.name}&nbsp;&nbsp;<g:checkBox name="sellingcompanies" optionKey="id" value="${item.id}" /> <br> 
      </g:each> 
     <!-- end here by rsheyeah --> 
     </td> 
    </tr> 
    <!-- ... snip ... --> 

बेस्ट हिस्सा दिखाया गया है कि grails के वर्तमान संस्करण में आप अभ्यस्त उपयोग करने के लिए के रूप में डेनियल ने उल्लेख किया है और इन मूल्यों को स्वचालित रूप से द्वारा नियंत्रित किया जाएगा "स्ट्रिंग के रूप में समतल()" की जरूरत है grails और शामिल तालिका में बने रहेंगे। आपको यह सुनिश्चित करने की ज़रूरत है कि आपके चेकबॉक्स में सही नाम और मूल्य है।

उम्मीद है कि यह मदद करता है !!

संबंधित मुद्दे