在自己的域上进行 Grails 验证

Posted

技术标签:

【中文标题】在自己的域上进行 Grails 验证【英文标题】:Grails validation over own domain 【发布时间】:2015-08-18 22:48:18 【问题描述】:

我正在使用 Grails 2.4.2 并且有一个类 Contract,其中包含许多 InvoiceRecipient。 InvoiceRecipients 类有一个属性 invoiceType,它有 2 个可能的值,'O' 用于发票原件,'C' 用于发票-复制。您可以想象,对于一份合同,InvoiceRecipients 只允许一条类型为 'O' 的记录。

如果我尝试按照以下代码片段来实现它,VM 会运行到 ***。

我尝试的另一种方法是一种服务方法,它遍历合同的收件人数组以计算 invoiceType 为“O”的记录,或者我尝试通过 InvoiceRecipient.countByContractAndInvoiceType() 进行选择计数以确定“O”的数量在控制器中的contract->invoiceRecipients 关系中。

在最后两种情况下,Hibernate 都会为我当前的 InvoiceRecipient 记录生成一条更新语句,我会尝试对其进行验证。即使当前 InvoiceRecipient 的验证失败并且我填充了实例的错误对象,记录也已经更新(没有问题,因为约束未编码到类中并且在“保存”中不会引发错误。)并且我在数据库中有逻辑错误的记录。

class Contract implements Serializable 
    ...
    static hasMany = [recipients: InvoiceRecipient]
    ...


class InvoiceRecipient implements Serializable 
    static belongsTo = [contract: Contract]
    ...
    String invoiceType
    ...

    static constraints = 
        invoiceType nullable: false, maxLength: 1, inList: ['O', 'C'], validator:  val, obj ->
        /* => This generates a ***
        if (InvoiceRecipient.countByContractAndInvoiceType(obj.contract, 'O') > 1)
            return "invoiceRecipient.original.max.exceed"
        */
    

【问题讨论】:

【参考方案1】:

我可能会使用这样的东西:

validator:  val, obj ->
if (obj.recipients.findAllinvoiceType == 'O'.size() > 1)
        return "invoiceRecipient.original.max.exceed"

这样您应该能够防止 Hibernate 尝试刷新脏对象并在此过程中重新验证该对象。

【讨论】:

啊,太好了,就像一个魅力!我很少使用 find-Methods... 我唯一需要更改的是 **it.**invoiceType == 'O'。

以上是关于在自己的域上进行 Grails 验证的主要内容,如果未能解决你的问题,请参考以下文章

验证自己的项目能不能发布

在 grails 中获取分离的域实体

TensorFlow:在我自己的图像上进行训练

Grails 覆盖默认的电子邮件验证

Laravel 重定向离开方法重定向到自己的域

Grails,Field 的域类默认值