在grails中保存具有多对多关系的对象

发布于 2024-10-21 20:10:08 字数 12070 浏览 4 评论 0原文

我正在尝试保存具有多对多关系的对象。一个 SellingCompany 可以拥有多个帐户,一个帐户可以与多个 SellingCompanies 关联。因此,SellingCompaniesAccount 中存储的表之间存在多对多关系

我的 Account_Info 域如下:

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}"
    }
}

我的 SellingCompanies 域如下:

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 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 文件中的表单包含实际上迭代所有不同的 SellingCompanies 并显示为复选框的代码。

<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])
        }


    }

}

现在,由于出现像 _ sellcompanies_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 在浏览器中解析为: 在此处输入图像描述

提前致谢

I am trying to save objects having Many-Many Relationship . A SellingCompany can have many Accounts and an Account can be associated with many SellingCompanies. So there is a many-many relationship between the tables stored in SellingCompaniesAccount

My Account_Info domain is as follows:

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}"
    }
}

My SellingComapanies domain is as follows:

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 }
}

The table that holds the Many-Many relationship is as follows:

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]

        }

}

The form in the create.gsp file contains the code that actually iterates over all the different SellingCompanies and displays as a check-box.

<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}  <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>

Lastly the controller which handles the save and list functions.

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])
        }


    }

}

Now, I am getting the following error, due to the empty hidden values appearing like _sellingcompanies_1 etc.:

Error Logs:

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)

First of all, where does the hidden values come from and is this approach fine to commit the the Many-Many relationship info in SellingCompaniesAccount controller class. Any better technique of doing this.

The create.gsp resolves to this in the browser:
enter image description here

Thanks in advance

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二智少女猫性小仙女 2024-10-28 20:10:08

如果其他人也遇到同样的问题,那么 Daniel 的上述答案绝对正确,只需从 Grails 2.7.8 开始添加一些更改即可。

所有复选框都将具有相同的 value = "${item.id}"name =" sellcompanies" ,如下所示:

<!-- ... 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}  <g:checkBox name="sellingcompanies" optionKey="id" value="${item.id}" /> <br>
            </g:each>
        <!--  end here by rsheyeah -->
        </td>
    </tr>
    <!-- ... snip ... -->

最好的部分是,在当前版本的 Grails 中,您不会需要使用 flatten() as string 正如 Daniel 提到的,这些值将自动由 Grails 处理并保留在连接表中。您需要确定的是您的复选框具有正确的名称和值。

希望有帮助!

If anyone else is having the same problem then the above answer by Daniel is absolutely correct just adding few changes as of Grails 2.7.8.

All checkbox will have same value = "${item.id}" and name ="sellingcompanies" as shown 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}  <g:checkBox name="sellingcompanies" optionKey="id" value="${item.id}" /> <br>
            </g:each>
        <!--  end here by rsheyeah -->
        </td>
    </tr>
    <!-- ... snip ... -->

Best part is that in present version of Grails you wont need to use flatten() as string as mentioned by Daniel and these values will automatically be handled by Grails and will be persisted in the join table. All you need to be sure is your checkbox have correct name and value.

Hope it helps!

情徒 2024-10-28 20:10:08

问题出在这段代码上:

    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< /em>”然后什么也不做;该部分的第二部分检查参数键是否包含“salescompanies_”,然后尝试从该参数值中提取后缀数字。对于键值为“_ sellcompanies_5”的参数,第一个测试和第二个测试的计算结果都为 true,因此在第二个测试中,您要从参数键值,您剩下“_5”,然后您尝试将其计算为整数。不幸的是,“_5”不是有效的整数值,因此您给出了错误。

您可以通过执行以下操作非常简单地解决此问题:

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

处理此问题的更好方法可能是更改您的 gsp 为每个销售公司提供相同的命名参数,然后循环遍历实际应用的值。像这样的事情:

        <!-- ... 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}  <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) }

这应该确保您正确评估从模型对象传递的适当值,而不是侵入检索方法。

希望这有帮助!

The problem is with this piece of code:

    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)
    }

Your params from the form post are:

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"]

The test in your loop first checks if the parameter key contains "_sellingcompanies" and then it does nothing; the second part of that checks if the parameter key contains "sellingcompanies_" and then it tries to pull the suffixed number off of that parameter value. In the case of a parameter with the key value "_sellingcompanies_5", both the first test and the second test evaluate to true, so in the second test, you are subtracting the "sellingcompanies_" off of the parameter key value and you are left with "_5", which you are then trying to evaluate to an Integer. Unfortunately, "_5" is not a valid Integer value, and hence your given error.

You can solve this very simply by doing the following:

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

Probably a better way to handle this though would be to change your gsp to give the same named parameter for each of the sellingcompanies, and then looping through the actual applied values. Something like this:

        <!-- ... 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}  <g:checkBox name="sellingcompanies" optionKey="id" value="${item.id}" /> <br>
                </g:each>
            <!--  end here by rsheyeah -->
            </td>
        </tr>
        <!-- ... snip ... -->

Then in your controller do something like this:

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

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

This should ensure that you are properly evaluating the appropriate values that have been passed from your model object, and not hacking in a retrieval method.

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文