Groovy / Grails:增强静态闭包

时间:2009-11-15 03:40:52

标签: grails groovy

我正在寻找一种修改/更改现有闭包的方法。但是,我不想覆盖它;相反,我想加强它。

这是一个简单的例子。假设我们有一个Address对象:

class Address {
    String street
    String city
    String state
    String zipCode

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

这将是一个很好的例子,因为它也是一个有效的Grails域对象。 我要做的是在运行时/动态地向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 )
    }
}

请注意新的zipCode约束? 我知道我可以通过metaClass覆盖它来改变约束。但是,这里的目标不是在一个过程中伤害任何人,因此我只想添加到现有的闭包。

3 个答案:

答案 0 :(得分:3)

您确实可以在运行时更改约束。

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

答案 1 :(得分:2)

我想你可能在这里运气不好。据我所知,Grails开发人员不希望您在运行时修改约束。约束存储在

org.codehaus.groovy.grails.commons.DefaultGrailsDomainClass

其中约束本身存储为私有映射,具有唯一的访问者

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

约束闭包由org.codehaus.groovy.grails.validation.ConstrainedPropertyBuilder处理。

您显然可以编写自己的具有可修改约束对象的DomainClass类,并将其注入基于Spring的初始化,但我怀疑这是您可能不想采用的路径。

其他想法 - 我不知道zipCode约束的具体示例,但许多约束强制执行数据库列约束,因此在运行时添加这些约束可能会导致奇怪的行为。我认为使用自定义约束验证器会更容易避免奇怪的数据库错误。

<强>更新

再看一下,我发现DefaultGrailsDomainClass有refreshConstraints()方法,这似乎强制重新评估约束关闭,虽然我仍然不确定你是否可以修改闭包本身,或者为什么这个功能存在于第一名。

在1.2 Grails中添加了共享约束 - 我想知道你是否可以创建一个zipCode共享约束,以某种方式修改它,然后调用refresh。

答案 2 :(得分:0)

想想也许我不理解,因为你也可以把它看作域级验证......你能不能吗?