如何在 grails 域子类中添加对继承属性的约束
Posted
技术标签:
【中文标题】如何在 grails 域子类中添加对继承属性的约束【英文标题】:How to add constraints on inherited properties in a grails domain sub-class 【发布时间】:2011-04-25 10:49:12 【问题描述】:这是我想做的:
class A
String string
static constraints =
string(maxSize:100)
class B extends A
static constraints =
string(url:true)
所以类 A 应该有 一些 约束,而 B 应该在同一属性上具有 相同的加额外 约束。
但我无法让它工作,我可以想象它会与每层次结构表的概念发生冲突。
所以我尝试通过引入具有 B 类约束的 Command 对象来解决该问题,该约束可以在 B 类的构造函数中进行验证。但是,Command 对象似乎只能在控制器中使用(grails 一直说有没有 .validate() 方法)。
所以我的问题是:使用 grails 约束解决这个问题的最优雅的方法是什么(不是手动重新实现验证)?可能是……
切换到 Table-per-Sub-Class 概念? 以某种方式使命令对象在 Domain 类中工作? 还有其他方法吗?编辑:我可以在子类中定义所有约束,重复父类的约束,甚至在父类中根本没有约束。但该解决方案应该适用于同一父类的多个子类(具有不同的约束)。
【问题讨论】:
我不确定每个约束都会以这种方式工作,因为默认情况下继承的类映射到同一个数据库表。因此,如果您的 C 类在 Cc 上具有非空的唯一约束,它将对整个表 A 施加 DB 表约束 - 所有类都将存在 c 字段,并且对于除 C 实例之外的任何内容都将为空。 是的,这就是我使用 Table-per-Sub-Class 的原因。 【参考方案1】:你可以使用
class B extends A
static constraints =
importFrom A
//B stuff
如http://grails.org/doc/latest/ref/Constraints/Usage.html中所述
【讨论】:
【参考方案2】:2.x 中的样子:
由于约束是由某些 ConstraintsBuilder 执行的闭包,我会尝试从 B 调用它,例如
class B extends A
static constraints =
url(unique: true)
A.constraints.delegate = delegate # thanks Artefacto
A.constraints()
【讨论】:
关闭。不过,您必须先更改A.constraints
的代表:A.constraints.delegate = delegate
。但是感谢您为我指明了正确的方向。
@Artefacto - 您能否发布有效的答案,或编辑此答案以使其有效?我知道其他人也有这个问题。谢谢!
我已经用 grails 2.0.4(使用 grails 控制台)尝试过它,但它不起作用,它在 A.contraints 没有委托属性的阶段引发错误【参考方案3】:
基本上我看不出它是怎么做到的。
在设计方面,域类实际上映射了数据库表的结构。约束实际上会生成数据库约束。因此,您正在尝试制作多个对象,这些对象将在同一张表上生成不同的约束。
我认为更好的方法是创建一个具有最简单约束子集的域对象,然后使用不同的命令对象来微调要传递给域的确切约束。
您还可以使用验证器:在约束中为不同的对象类型微调不同的约束(类似于域中的类型列并根据不同的类型进行不同的验证)。
【讨论】:
【参考方案4】:您需要重新声明超类约束,因为它是一个静态 clojure(静态属性和静态方法不会被子类继承),因此它不会被 GORM 映射。
干杯。
【讨论】:
以上是关于如何在 grails 域子类中添加对继承属性的约束的主要内容,如果未能解决你的问题,请参考以下文章