10 バリデーション - Reference Documentation
Authors: Graeme Rocher, Peter Ledbrook, Marc Palmer, Jeff Brown, Luke Daley, Burt Beckwith
Version: 2.3.0
Translated by: T.Yamamoto, Japanese Grails Doc Translating Team. Special thanks to NTT Software.
【注意】このドキュメントの内容はスナップショットバージョンを元に*意訳*されているため、一部現行バージョンでは未対応の機能もあります。
Table of Contents
10 バリデーション
constraints
)によってバリデーションを定義するすてきな仕組みを持っています。10.1 制約を宣言
class User { String login String password String email Integer agestatic constraints = { … } }
class User { ...static constraints = { login size: 5..15, blank: false, unique: true password size: 5..15, blank: false email email: true, blank: false age min: 18 } }
login
property must be between 5 and 15 characters long, it cannot be blank and must be unique. We've also applied other constraints to the password
, email
and age
properties.login
プロパティに対して5~15文字の長さとし(size
)、空白(blank
)を許可せず、一意となる(unique
)よう制約を与えています。password
、email
、age
の各プロパティについても同様に制約を宣言しています。
By default, all domain class properties are not nullable (i.e. they have an implicit nullable: false
constraint).
デフォルトでは、すべてのドメインクラスのプロパティはnull値を許容しません(暗黙にnullable: false
制約を持っています)。
java.util.Date
.java.util.Date
のインスタンスのような値を必要とするかもしれないため、制約が評価されるのは一度だけであることに注意してください。class User { ...static constraints = { // this Date object is created when the constraints are evaluated, not // each time an instance of the User class is validated. birthDate max: new Date() } }
class User { ...static constraints = { // この Date 型オブジェクトは制約が評価されるときに作られます。 // User クラスのインスタンスがバリデーションされる度に作られるわけではありません。 birthDate max: new Date() } }
忠告 - 制約からドメインクラスのプロパティを参照するとき
MissingPropertyException
for your trouble. For example, you may tryMissingPropertyException
が発生します。たとえば、以下のようなコードを試してみると…class Response { Survey survey Answer answerstatic constraints = { survey blank: false answer blank: false, inList: survey.answers } }
inList
constraint references the instance property survey
? That won't work. Instead, use a custom validator:inList
制約においてインスタンスプロパティであるsurvey
を参照すると、これは動作しません。代わりに、カスタムvalidatorを使いましょう:class Response { … static constraints = { survey blank: false answer blank: false, validator: { val, obj -> val in obj.survey.answers } } }
obj
argument to the custom validator is the domain instance that is being validated, so we can access its survey
property and return a boolean to indicate whether the new value for the answer
property, val
, is valid.obj
は、バリデーションされるドメインクラスの インスタンス です。こうすることでsurvey
プロパティにアクセスし、answer
プロパティの新しい値としてval
がsurvey.answers
に含まれるかどうかを示す真偽値を得ることができます。
10.2 制約をバリデートする
バリデーションの基礎
def user = new User(params)if (user.validate()) { // do something with user } else { user.errors.allErrors.each { println it } }
errors
property on domain classes is an instance of the Spring Errors interface. The Errors
interface provides methods to navigate the validation errors and also retrieve the original values.errors
プロパティは、SpringのErrorsインターフェイスのインスタンスです。Errors
インターフェイスは、バリデーションエラーの参照や元の値の取得などのメソッドを提供します。バリデーションのフェーズ
def user = new User(params)
errors
property due to type conversion (such as converting Strings to Dates). You can check these and obtain the original input value using the Errors
API:errors
プロパティが存在する場合があります(文字列を日付に変換しようとするなど)。Errors
APIを使用することで、エラーの有無や元の入力値を取得することができます:if (user.hasErrors()) { if (user.errors.hasFieldErrors("login")) { println user.errors.getFieldError("login").rejectedValue } }
validate
before executing, allowing you to write code like:validate
を呼び出すので、次のようなコードが書けます:if (user.save()) { return user } else { user.errors.allErrors.each { println it } }
10.3 制約をクラス間で共有する
Global Constraints
グローバル制約
grails-app/conf/Config.groovy
:
grails-app/conf/Config.groovy
内でも制約を定義できます。grails.gorm.default.constraints = { '*'(nullable: true, size: 1..20) myShared(nullable: false, blank: false) }
class User { ...static constraints = { login shared: "myShared" } }
shared
argument, whose value is the name of one of the constraints defined in grails.gorm.default.constraints
. Despite the name of the configuration setting, you can reference these shared constraints from any validateable class, such as command objects.
shared
引数にはgrails.gorm.default.constraints
内に定義した制約の名前の1つを指定していることに注目してください。
このように設定ファイル内の名前であるにもかかわらず、コマンドオブジェクトのようなバリデーション可能なクラスから共有された制約を参照できます。'*'
に関連した制約(上記の例ではnullable
とsize
)はバリデーション可能なクラス内のすべてのプロパティへ適用されます。
これらのデフォルト設定はバリデーション可能なクラス内で宣言する制約によって上書き可能です。Importing Constraints
制約をインポートする
class User { String firstName String lastName String passwordHashstatic constraints = { firstName blank: false, nullable: false lastName blank: false, nullable: false passwordHash blank: false, nullable: false } }
UserCommand
, that shares some of the properties of the domain class and the corresponding constraints. You do this with the importFrom()
method:
importFrom()
メソッドで実現できます:class UserCommand { String firstName String lastName String password String confirmPasswordstatic constraints = { importFrom User
password blank: false, nullable: false confirmPassword blank: false, nullable: false } }
User
domain class and apply them to UserCommand
. The import will ignore any constraints in the source class (User
) that don't have corresponding properties in the importing class (UserCommand
). In the above example, only the 'firstName' and 'lastName' constraints will be imported into UserCommand
because those are the only properties shared by the two classes.
User
ドメインクラスからすべての制約をインポートし、UserCommand
へこれらの制約を適用します。
このインポートは、インポート先のクラス(UserCommand
)に関係がないプロパティの場合、インポート元のクラス(User
)内のそのプロパティの制約を無視します。
上記の例では、firstName
とlastName
のみが両方のクラスで共有されてるため、これらの制約のみがUserCommand
へインポートされます。include
and exclude
arguments. Both of these accept a list of simple or regular expression strings that are matched against the property names in the source constraints. So for example, if you only wanted to import the 'lastName' constraint you would use:
include
とexclude
の引数が使えます。
両者ともに、インポート元の制約のプロパティ名に一致する単なる文字列、または正規表現文字列のリストを受け取ります。
例えば、lastName
制約だけをインポートしたい場合は以下のように使います:… static constraints = { importFrom User, include: ["lastName"] … }
Name
で終わるすべての制約をインポートしたい場合:…
static constraints = {
importFrom User, include: [/.*Name/]
…
}
exclude
does the reverse, specifying which constraints should not be imported.
exclude
はこの逆で、インポートすべきでない制約を指定します。
10.4 クライアントサイドバリデーション
Displaying Errors
エラーを表示する
<g:renderErrors bean="${user}" />
<g:hasErrors bean="${user}"> <ul> <g:eachError var="err" bean="${user}"> <li>${err}</li> </g:eachError> </ul> </g:hasErrors>
Highlighting Errors
エラーをハイライトする
<div class='value ${hasErrors(bean:user,field:'login','errors')}'> <input type="text" name="login" value="${fieldValue(bean:user,field:'login')}"/> </div>
login
field of the user
bean has any errors and if so it adds an errors
CSS class to the div
, allowing you to use CSS rules to highlight the div
.
user
ビーンのlogin
フィールドにエラーがあるかどうかをチェックし、エラーがある場合にはdiv
にerros
というCSSのクラスを追加するので、dev
をハイライトするCSSルールが使えるようになります。Retrieving Input Values
入力値を取得する
<input type="text" name="login" value="${fieldValue(bean:user,field:'login')}"/>
FieldError
in the User
bean and if there is obtain the originally input value for the login
field.
User
ビーン内にFieldError
が存在するかチェックし、もし存在する場合はlogin
フィールドに対する元の入力値を取得します。
10.5 バリデーションの国際化
Constraints and Message Codes
制約とメッセージコード
package com.mycompany.myappclass User { ...
static constraints = { login size: 5..15, blank: false, unique: true password size: 5..15, blank: false email email: true, blank: false age min: 18 } }
[Class Name].[Property Name].[Constraint Code]
blank
constraint this would be user.login.blank
so you would need a message such as the following in your grails-app/i18n/messages.properties
file:
blank
制約の場合はuser.login.blank
となり、grails-app/i18n/messages.properties
ファイル内に以下のようなメッセージが必要です:user.login.blank=Your login name must be specified!
com.mycompany.myapp.User.login.blank
はuser.login.blank
よりも先に使われます。
これによりドメインクラスのメッセージコードがプラグインと競合した場合でも競合を回避できます。Displaying Messages
メッセージを表示する
<g:hasErrors bean="${user}"> <ul> <g:eachError var="err" bean="${user}"> <li><g:message error="${err}" /></li> </g:eachError> </ul> </g:hasErrors>
error
argument to read the message for the given error.
error
引数を組み合わせて使用しています。10.6 コマンドオブジェクト、ドメインクラス以外のバリデーション
constraints
property in the class (as described above) and then telling the framework about them. It is important that the application register the validateable classes with the framework. Simply defining the constraints
property is not sufficient.
constraints
プロパティを定義し、それからフレームワークにこのクラスを教えてあげることで、バリデーション可能にすることができます。
アプリケーション側からバリデーション可能なクラスをフレームワークに登録するということが重要です。
単にconstraints
プロパティを定義しただけでは十分ではありません。The Validateable Annotation
Validateableアノテーション
constraints
property and are annotated with @Validateable can be made validateable by the framework. Consider this example:
constraints
プロパティを定義し、@Validateable
を付与することでフレームワークによってバリデーション可能となります。
例えば:// src/groovy/com/mycompany/myapp/User.groovy package com.mycompany.myappimport grails.validation.Validateable
@Validateable class User { ...
static constraints = { login size: 5..15, blank: false, unique: true password size: 5..15, blank: false email email: true, blank: false age min: 18 } }
Registering Validateable Classes
バリデーション可能なクラスの登録
Validateable, it may still be made validateable by the framework. The steps required to do this are to define the static
constraints property in the class (as described above) and then telling the framework about the class by assigning a value to the
grails.validateable.classes property in
Config.groovy@:
@Validateable
が付与されていなくても、フレームワークによってバリデーション可能になっている場合があります。
アノテーションなしでバリデーション可能にするには、(前述したように)そのクラス内で静的なconstraints
プロパティを定義し、それからConfig.groovy
内のgrails.validateable.classes
プロパティに値を設定してフレームワークにこのクラスを教えてあげる必要があります:grails.validateable.classes = [com.mycompany.myapp.User, com.mycompany.dto.Account]