来自Rails背景我很高兴看到Grails 2.0.x支持Model.findOrSaveBy*
和Model.findOrCreateBy*
形式的动态查找器。但是,该功能极其人为限制 - 根据documentation,该方法接受 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 allows you to do this通过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)
但它似乎非常重复。有什么建议?谢谢。
答案 0 :(得分:1)
根据您的示例,一个简单的解决方案是在域类中为颜色提供默认值:
class Car {
String color = "red"
String license
static constraints = {
license blank: false, unique: true
color blank: false, inList: ["red", "black"]
}
}
然后以下内容应该有效:
Car.findOrSaveByLicense("UVWXYZ")