2

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)

しかし、それは非常に繰り返しのようです。助言がありますか?ありがとう。

4

1 に答える 1

1

あなたの例に基づいて、簡単な解決策は、ドメインクラスの色にデフォルト値を与えることです:

class Car {
  String color = "red"
  String license

  static constraints = {
    license blank: false, unique: true
    color blank: false, inList: ["red", "black"]
  }
}

次に、以下が機能するはずです。

Car.findOrSaveByLicense("UVWXYZ")
于 2012-10-04T20:30:51.563 に答える