简体   繁体   English

Groovy / Grails:增强静态封闭

[英]Groovy / Grails: Enhance a Static Closure

I am looking for a way to modify/change an existing closure. 我正在寻找一种修改/更改现有闭包的方法。 However, I do not wish to overwrite it; 但是,我不想覆盖它。 instead I would like to enhance it. 相反,我想增强它。

Here is a quick example. 这是一个简单的例子。 Let's say we have an Address object: 假设我们有一个Address对象:

class Address {
    String street
    String city
    String state
    String zipCode

    static constraints = {
        street( nullable:true )
        city( blank:false )
        state( size:2..2 )
    }
}

It would be a good example, because it is also a valid Grails domain object. 这将是一个很好的例子,因为它也是有效的Grails域对象。 What I am looking to do is to add another constraint at runtime / dynamically to the Address class: 我想要做的是在运行时/动态地向Address类添加另一个约束:

class Address {
    String street
    String city
    String state
    String zipCode

    static constraints = {
        street( nullable: true )
        city( blank: false )
        state( size: 2..2 )
        zipCode( size: 5..6 )
    }
}

Notice that new zipCode constraint? 注意新的zipCode约束吗? I understand that I can change the constraints all together by overriding it through the metaClass ; 我知道可以通过metaClass重写约束,从而一起改变所有约束。 however, the goal here is not to hurt anybody in a process, hence I just want to add to the existing closure. 但是,这里的目标不是在过程中伤害任何人,因此我只想添加到现有的闭包中。

You can indeed change constraints at runtime. 您确实可以在运行时更改约束。

ConstrainedProperty constrainedProperty = Address.constraints.zipCode
constrainedProperty.setSize(5..6)

I think you might be out of luck here. 我想您可能在这里不走运。 From what I can tell, Grails developers don't want you to modify constraints at runtime. 据我所知,Grails开发人员不希望您在运行时修改约束。 Constraints are stored in 约束存储在

org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass

where constraints themselves are stored as a private map, with the only accessor 约束本身存储为私有映射,只有访问者

public Map getConstrainedProperties()
{
       return Collections.unmodifiableMap(this.constraints);
}

The constraints closure is processed by org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilder. 约束关闭由org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilder处理。

You can obviously write your own DomainClass class that has a modifiable constraints object, and inject that one into Spring-based initialization, but I suspect that's a path that you might not want to take. 显然,您可以编写自己的DomainClass类,该类具有可修改的约束对象,然后将其注入基于Spring的初始化中,但是我怀疑这是您可能不希望采用的路径。

Additional thought - I don't know the specific example for zipCode constraint, but many of the constraints enforce database column constraints, so adding those at runtime can probably lead to weird behavior. 另外的想法-我不知道zipCode约束的具体示例,但是许多约束都强制执行数据库列约束,因此在运行时添加这些约束可能会导致奇怪的行为。 I think using custom constraint validators would be easier for you to avoid weird database bugs. 我认为使用自定义约束验证器将更容易避免怪异的数据库错误。

Update 更新

Looking on it some more, I found DefaultGrailsDomainClass has refreshConstraints() method, which seems to force re-evaluation of the constraints closure, although I still am not sure if you can modify the closure itself, or why this functionality exists in the first place. 再看一下,我发现DefaultGrailsDomainClass具有refreshConstraints()方法,该方法似乎迫使重新评估约束闭包,尽管我仍然不确定是否可以修改闭包本身,或者为什么此功能首先存在。

In 1.2 Grails added shared constraints - I wonder if you could create a zipCode shared constraint, modify it somehow, and then call refresh. 在1.2 Grails中添加了共享约束-我想知道是否可以创建一个zipCode共享约束,以某种方式对其进行修改,然后调用refresh。

认为我可能不太理解,因为您也可以将其视为域级别验证...可以吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM