バリデーションの実行
では、addで実行している処理を見てみましょう。ざっと見たところ、バリデーションの処理を行っているような部分は見当たりません。それもそのはず、実をいえばifの条件部分で実行している「board.save()」が、そのための部分なのです。
ドメインクラスでconstraintsを設定してあると、そのインスタンスでsaveを実行した際に、自動的に用意されているバリデーションのチェックを行うようになっています。すべてのチェックに合格するとレコードの保存が行われます。
もしバリデーションでエラーが発生すると、レコードの保存は行われず、saveの実行結果としてfalseが返されます。従って、ここでの例のように「if (board.save())」と実行して、elseにエラー時の処理を用意すればよいのです。
ここでは、バリデーションの結果がfalseだった場合、発生したエラーからフィールド名を取り出して出力しています。このように処理を行っていますね。
board.errors.allErrors.each {……}
発生したエラーは、「ドメインクラス.board.errors.allErrors」として取り出すことができます。これはorg.springframework.validation.FieldErrorというクラスの配列として得られます。ここでは、eachを使い、その1つ1つについて繰り返し処理をしています。FieldErrorには、発生したフィールド名を返す「getField」というメソッドがあり、これを呼び出してエラーの発生したフィールド名をprintlnしていたわけです。
主なバリデーションルール
ここでは、最もシンプルなblankというバリデーションのルールを使いましたが、このバリデーションルールは標準で多数のものが用意されています。ここで、主なものについて整理しておきましょう。
| ルール | 説明 |
| blank | 既に登場しました。空白を許可するか否かを指定します。falseにすると必須項目となります。 |
| creditcard | クレジットカード番号の入力をチェックするものです。trueに設定すると、クレジットカード番号として認識できる値のみが入力可能となります。 |
| メールアドレスのチェックを行うためのものです。trueにすると、メールアドレスとして認識できる値のみが入力可能になります。 | |
| inList | あらかじめ用意されたリストに含まれている値のみ許可するものです。これは、inList["A","B","C"]というように、配列として値を指定します。 |
| length | 文字数の範囲を指定するものです。これは、length:5..10というように、rangeの値を使ってその範囲を指定します。 |
| min | クラスを値として設定する際、最小値を指定するものです。これは、そのクラスがComparableである必要があります。 |
| minLength | テキストの文字数や配列の要素数の最小値を指定するものです。整数で値を指定します。 |
| minSize | コレクションや数値の最小値を指定するものです。数値で指定します。 |
| matches | あらかじめ用意された正規表現パターンにマッチするかどうかをチェックします。パターンのテキストを値に指定します。 |
| max | クラスを値として設定する際、最大値を指定するものです。これは、そのクラスがComparableである必要があります。 |
| maxLength | テキストの文字数や配列の要素数の最大値を指定するものです。整数で値を指定します。 |
| maxSize | コレクションや数値の最大値を指定するものです。数値で指定します。 |
| notEqual | 指定した値と等しくないかどうかを調べます。 |
| nullable | nullの値を許可するかどうかを指定します。trueにするとnull値を許可します。 |
| range | 指定された範囲内の値のみを許可します。値はrangeを使い、range:5..10といった形で指定します。 |
| size | コレクションや数値の範囲を指定するものです。値には、rangeを使い、size:5..10といった形で指定します。 |
| unique | ユニークな値のみ許可します。データベースに持続的接続が行われ、まだ値が登録されていない場合のみ受け付けます。 |
| url | URLとして扱える値かどうかをチェックするものです。trueに設定すると、URLとして認識可能な値だけが許可されます。 |
これは筆者の環境の問題かも知れませんが、動作確認中、バリデーションの中で、テキストの文字数に関連するものだけが、なぜかチェックを素通りしてしまうという現象が見られました。バージョンによる現象かもしれませんので、利用の際にはそれぞれで動作確認をしてみてください。
エラーメッセージの表示
作成したサンプルのaddアクションを使ってみると、入力チェックではじかれた場合、エラーメッセージなどがまったく表示されないため、何がどうなっているのかこのままでは分かりません。そこで、エラーメッセージを表示するように修正をしてみましょう。まずは、コントローラー側です。
def add = {
if (request.getMethod() == 'POST'){
def board = new Boards(params)
if (board.save()){
redirect(action:index)
} else {
render(view:'add',model:[board:board])
}
}
}
ここでは、board.saveを行ったとき、結果がfalseだった場合の処理(else以降)で、「render」というメソッドを実行しています。これは、ビューをレンダリングするものです。引数にビューとモデルをそれぞれ指定してレンダリングを実行します。これにより、addビューが再度レンダリングされ画面に表示されます。
後は、addのビュー(add.gsp)に、エラーメッセージを表示するための処理を追加しておきます。フォームの手前あたりに、
<g:hasErrors bean="${board}>
<g:renderErrors bean="${board}" as="list" />
</g:hasErrors>
このようにタグを追加しておきましょう。<g:hasErrors>は、beanに指定したインスタンスにエラーが存在する場合のみ実行されるタグです。その中にある<g:renderErrors>は、エラーをレンダリングし出力するためのもので、beanにエラーを調べるインスタンス、asに出力形式("list"でそれぞれをリスト表示します)を指定します。

