7

場所を作るためのフォームがあります。国によっては、州(州、地域)フィールドが必須かどうかが決まります。

必須でない場合は、空の文字列ではなく、nullにします。すべての空のフォームフィールドをnullにするコードがあります:

def newparams = [:]
        place = new Place()
        params.each() { k, v ->
            if (v instanceof String && place.hasProperty(k)) {
                if (!v.trim().length()) {
                    newparams[k] = null
                } else {
                    newparams[k] = v
                }
            }
        }

        place = new Place(newparams)
        place.validate()

現在、プレイスドメインには、州のバリデーターがあります。

province validator:  {val, obj -> if (obj.country in obj.requiresRegionCountries() && !obj.province) return [province.required]}

このルールでは、必要かどうかにかかわらず、常に「州をnullにすることはできません」と表示されます。

これは、デフォルトでfalseに設定されているnull許容バリデーターが原因だと思います。

nullable:trueを追加している場合、Provinceが必要な場合でも、カスタムバリデーターはスキップされ、空のProvinceで保存できます(nullでインスタンス化されるためだと思います)

今、私はどういうわけか私のカスタムバリデーターと私のバリデーターでnullableを指定する機能が必要です、次のようなものです:

province validator:  {val, obj -> 
  if (obj.country in obj.requiresRegionCountries() && !obj.province) { 
    nullable: false
    return [province.required] }
  else {
    nullable: true
  }
}

Grails 2.0.3でこれをどのように達成できますか?

4

2 に答える 2

13

多くの調査とフィードバックの結果、機能している2つのソリューションを見つけました。1つはコントローラーにあります。モデルに検証を追加せず、コントローラーから動的に追加します。

class PlacesController {
  def create() {
  def place = new Place(params.address)
  if (place.country in placesThatRequiresProvinceArray) {
      place.constrains.province.nullable = false
  } else {
      place.constrains.province.nullable = true
  }

}

もう1つの解決策は、このスレッドでTriによって提案されたものですが、null許容制約の前にカスタムバリデーターを配置します(そうでない場合、カスタムバリデーターはnull値に対して呼び出されません)。

static constraints = {
  province (validator: {val, obj ->
    if (obj.country == 'Canada' && !val)
      return ['province.required']
  }, nullable: true)
}
于 2012-07-12T08:11:25.650 に答える
6

貼り付けたコードではわかりませんが、デフォルトの検証で州をnullにできないことが問題である場合は、州をnullに明示的に許可しようとしましたか?フィールドごとに複数のバリデーターを使用できます。したがって、元のコードに戻って、null許容のバリデーターも指定するだけです。

province nullable: true, validator:  {val, obj -> 
  if (obj != null && obj.country in obj.requiresRegionCountries() && !obj.province) 
    return [province.required]
}

編集:カスタムバリデーターでは、if条件でobjがnullになるのを防ぐこともできます。

EDIT2:Grails2.0.4で動作する上記の検証を示すデモプロジェクト

class Place {
String country
Province province

  static constraints = {
    province (nullable: true, validator: {val, obj ->
        if (obj.country == 'Canada' && !val) return ['province.required']
    })
  }
}

コントローラ...

 class MainController {
  def index() {
    def place = new Place(country: 'Canada')
    if (!place.validate()) {
        render "need province<br/>" + place.errors
    } else {
        render "cool"
    }

つまり、例のようなPlaceドメインインスタンスを作成するためにハードコードされたインデックスアクションを呼び出すことができるダミーコントローラーがあるということです。国の文字列のみを定義したので、カスタム検証のために国の文字列にロジックを入力できることに注意してください。Placeインスタンスを作成するときに州を定義しなかったため、nullにする必要があります。そのシナリオでは、応答ページは次のように出力します...

出力スニペット..。

need province 
grails.validation.ValidationErrors: 1 .... does not pass custom validation]

Placeからnullable:true制約を削除すると、エラーは期待どおりのnull値になります...

出力スニペット..。

need province
grails.validation.ValidationErrors: 1 .... cannot be null]
于 2012-07-06T14:30:17.410 に答える