【问题标题】:Grails validation with composite key使用复合键进行 Grails 验证
【发布时间】:2015-07-24 13:58:34
【问题描述】:

我遇到了一个复杂的场景,我们正在使用带有复合键的旧数据库,并且客户希望能够更改两个数据库 pk,“expenseDate”和“adjustmentNumber”。为了能够更改 pks,我必须使用 HQL 查询。现在,这当然导致了另一个验证问题。我的工作是填充一个域,以便我可以验证它。

到目前为止,一切正常,直到出现我想返回 UI 的验证错误。

我有以下 URL,它使用 recoveryDetail 控制器和 edit 操作来呈现页面。

http://localhost:8080/pisr/recoveryDetail/edit?division=ALBANY&peid=PI0003&orgkey=14046701&expenseDate=07-22-2015&adjustmentNumber=1

编辑操作

def edit() {
    //Parse clean url expense date
    params.expenseDate = new SimpleDateFormat('MM-dd-yyyy').parse(params.expenseDate)

    def recoveryDetailInstance = RecoveryDetail.get(new RecoveryDetail(params))

    if(recoveryDetailInstance == null) {
        redirect(uri:'/')
        return
    }

    [recoveryDetailInstance: recoveryDetailInstance, disabled: isdisabled(recoveryDetailInstance.batchOverride)]
}

还有下面的更新动作。

更新操作

@Transactional
def update() {
    params.pk_expenseDate = getDateParser(params.pk_expenseDate)
    params.expenseDate = getDateParser(params.expenseDate)
    params.adjustmentNumber = getAdjustementNumber(params)

    RecoveryDetail recoveryDetailInstance = new RecoveryDetail(params);
    recoveryDetailInstance.division = params.pk_division
    recoveryDetailInstance.peid = params.pk_peid
    recoveryDetailInstance.orgkey = params.pk_orgkey

    recoveryDetailInstance .validate()

    if(recoveryDetailInstance .hasErrors()) {                       
        flash.message = "test"
        respond view: "edit", model:[recoveryDetailInstance:recoveryDetailInstance]
        return
    } else {
        def sqlParams = [
            pk_division:params.pk_division,
            pk_peid:params.pk_peid,
            pk_orgkey:params.pk_orgkey,
            pk_expenseDate:params.pk_expenseDate,
            pk_adjustmentNumber:params.int('pk_adjustmentNumber'),
            approved:YesNoTypes.valueOf(params.approved),
            batchOverride:YesNoTypes.valueOf(params.batchOverride),
            adjustmentFlag:params.adjustmentFlag,
            adjustmentNumber:params.adjustmentNumber,
            projectHours:new BigDecimal(params.projectHours),
            percentEffort:new BigDecimal(params.percentEffort),
            totalHours:new BigDecimal(params.totalHours),
            expenseDate:params.expenseDate
        ]

        RecoveryDetail.executeUpdate(recoveryDetailQuery, sqlParams)
    }

编辑 gsp

            <g:form class="form-horizontal" url="[resource:recoveryDetailInstance, action:'update']" method="PUT">
                <!-- hidden fields contain params from url (composite key)-->
                <g:hiddenField name="pk_division" value="${recoveryDetailInstance?.division}"/>
                <g:hiddenField name="pk_peid" value="${recoveryDetailInstance?.peid}"/>
                <g:hiddenField name="pk_orgkey" value="${recoveryDetailInstance?.orgkey}"/>
                <g:hiddenField name="pk_expenseDate" value="${formatDate(format:'MM/dd/yyyy',date:recoveryDetailInstance?.expenseDate)}" />
                <g:hiddenField name="pk_adjustmentNumber" value="${recoveryDetailInstance?.adjustmentNumber}"/>

                <div class="row">
                    <div class="col-md-6">
                        <g:render template="form" model="[recoveryDetailInstance: recoveryDetailInstance, 'mode':'edit']"/>
                    </div>
                </div>
                <div class="form-group">
                    <div class="col-sm-offset-2 col-sm-10">
                        <g:actionSubmit class="btn btn-primary" action="update" disabled="${disabled}" value="${message(code: 'default.button.update.label', default: 'Update')}"/>
                    </div>
                </div>
            </g:form>

问题 当用户导致触发服务器端响应的验证错误时,我遇到了以下不同返回类型的问题。

redirect - 这将返回 flash 消息,但会将 gsp 重定向到 edit 操作,该操作又会触发初始化程序查询并将所有表单数据替换为原始数据。

示例 -

redirect (controller:"recoveryDetail", action:"edit", params:["division":params.pk_division, "peid":params.pk_peid, "orgkey": params.pk_orgkey, "expenseDate":params.expenseDate.format("MM-dd-yyyy"), "adjustmentNumber":params.adjustmentNumber])

respond - 所以我认为我只需要使用响应,结果如下。

URL 更改为 http://localhost:8080/pisr/recoveryDetail/update 删除所有参数并返回 404 页面。

例子

flash.message = "test"
            respond view: "edit", model:[recoverDetailInstance:recoverDetailInstance]
            return

所以我的问题

如何抛出服务器端验证错误并将其与用户输入的数据一起返回到页面?

【问题讨论】:

    标签: grails groovy


    【解决方案1】:

    您可以将参数重新添加到重定向或渲染调用中。

    redirect (..., params: params)
    

    https://grails.github.io/grails-doc/latest/ref/Controllers/redirect.html

    另外,我建议使用服务而不是控制器方法。服务已经是事务性的。如果hasErrors 为真,我也会抛出异常。异常消息或对象可以是您返回给用户的有效负载。

    【讨论】:

    • 我确实尝试了我的问题中演示的重定向调用,它重定向回原始编辑操作,导致它运行原始查询并替换所有数据。我不相信渲染会支持参数。一切正常后,我会将所有内容移至服务层。
    • 啊,对不起。错过了参数部分。
    • 所以我认为解决方案实际上是渲染,但没有使用参数。它只是呈现更新操作。
    【解决方案2】:

    解决方案是使用渲染而不使用这样的参数。

    if(recoveryDetailInstance.hasErrors()) {
        render view: "edit", model:[recoveryDetailInstance:recoveryDetailInstance]
        return
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-21
      • 2013-07-21
      • 2020-04-24
      • 2016-02-10
      • 1970-01-01
      • 2021-09-30
      • 2019-07-11
      • 2011-11-20
      相关资源
      最近更新 更多