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
呼び出しを傍受し、次のようなものに委任するドメイン クラスにa を追加できると思います。
def car = Car.findByLicense("UVWXYZ") ?: new Car(license: "UVWXYZ", color: "red").save(flush: true)
しかし、それは非常に繰り返しのようです。助言がありますか?ありがとう。