来自 Rails 背景,我很高兴看到 Grails 2.0.x 支持表单的动态查找器Model.findOrSaveBy*
和Model.findOrCreateBy*
. 但是,该功能受到极大的人为限制——根据文档,该方法接受n 个参数,其中n是方法调用中列出的属性的确切数量。例如:
class Car {
String color
String license
static constraints = {
license blank: false, unique: true
color blank: false, inList: ["red", "black"]
}
}
/* If there exists a Car(color: red, license: "ABCDEF") */
// WORKS
Car.findOrSaveByColor("red") // will find the car
Car.findOrSaveByLicense("ABCDEF") // will find the car
Car.findOrSaveByLicenseAndColor("UVWXYZ", "black") // will persist a new car
// DOES NOT WORK
Car.findOrSaveByLicense("UVWXYZ") // will fail because the color is not provided
Car.findOrSaveByLicense("UVWXYZ", color: "black") // will fail due to an extra parameter
Car.findOrSaveByLicenseAndColor("ABCDEF", "black") // will fail due to persisting a new instance because the color does not match, which then has a unique collision
我只关心通过唯一license
值定位,但如果对象不存在,我需要用所有必需的属性填充它。Rails 允许您通过Hash
参数来执行此操作,如下所示:
// Using findOrSaveBy* because Grails:"save"::Rails:"create" and "create" does not persist in Grails
Car.findOrSaveByLicense("ABCDEF", color: "red") // will find a car with that license plate regardless of color or persist a new entry with the license and color "red"
这个功能没有在 Grails 中实现是有原因的吗?在我看来,这极大地限制了这些动态查找器的有用性。我想我可以methodMissing
在域类中添加一个拦截调用并委托给类似的东西:
def car = Car.findByLicense("UVWXYZ") ?: new Car(license: "UVWXYZ", color: "red").save(flush: true)
但它似乎非常重复。有什么建议么?谢谢。