Skip to content

Instantly share code, notes, and snippets.

@nobeans
Created June 22, 2016 09:16
Show Gist options
  • Save nobeans/89d5677a5c85d0c7a317653f4e46e0e3 to your computer and use it in GitHub Desktop.
Save nobeans/89d5677a5c85d0c7a317653f4e46e0e3 to your computer and use it in GitHub Desktop.
Grails
★Slf4jをつけないと%lineなどがnullになる
Slf4jをつけるとマシになるけど、100%OKではないっぽい...
残っただめなのはAST変換部分?→しかたない系?
nullableなDateがクリアできない
Boolean,Double, IntegerはOK(nullクリアできる)
データバインディングで空文字が無視される
convertEmptyStringsToNull: false が関係している?
ユニットテストのデータバインディングでは、Dateに対する空文字がtypeMismatchになる
GrailsWebDataBinder#populateErrors()で、blank起因のエラーは無視するようになってた....
あまり筋が良くない気がするんだけども...
今回のようにシレっと反映されない、という問題が起きる
typeMismatch!と起こってもらった方が何が起こったかがわかりやすい
実装履歴見つけた
commit 22b81b93c9190a4535d4a2169dbcbf8ba6d06d47
Author: Graeme Rocher <[email protected]>
Date: Mon May 11 15:30:56 2009 +0100
fix for GRAILS-4485
なんだろう?
よくわからんが、value=""の場合のtypeMismatchはバリデーションエラーとして報告しない(起こるけど無視する)という仕様らしい
ではなぜユニットテストで無視されないのか?
GrailsWebDataBinder#populateErrors()で、grailsApplicationからGrailsDomainClassを解決できなかったため(null)、上記のBlank時エラー無視、という処理が実行されず、そのままtypeMismatchとして扱われた
→★これはこれでテスト時と実行時の挙動が違うのはよろしくない....
あと、blankがパースエラーになるのは同じだが、SimpleDataBinder#convert()で、run-app時はconversionHelpersを使って変換されるのに対して、test-app時はconversionServiceが使われていた(unit, integどちらも)。
★DateConversionHelper#convert()のバグっぽい
空文字ならnullを返せば良さそう
convertEmptyStringsToNull: trueの場合、コンバータ以前のGrailsWebDataBinder内の処理でnullに変換されるため、DateConversionHelperに渡される前のSimpleDataBinder#convert()で折り返されるため、正しくnullになって、更新にも成功する
(参考)数値のLocaleAwareNumberConverterは、""→nullに変換されている。コレに合わせる意味で↑の修正は良さそう。
BidingFormatを使うとまた別ルートになるっぽい
FormattedDateValueConverter
こっちはこっちでif文対処しないとParseExceptionがスローされる
(のに、run-appだとtypeMismatch扱いにならない....)
データバインディング整理
FORMで送信された値(非空文字)
型的に正しい
ドメイン上のプロパティにその値が設定される (値としてOKかどうかは後続のバリデーションで実施)
型的に不正
ドメイン上のプロパティがtypeMismatchエラーになる
FORMで送信された空文字
ドメイン上のプロパティに空文字が設定される (convertEmptyStringsToNull=false)
String: オプション的文字列フィールド(備考欄)、などであれば空文字のまま設定されるべき。実際される。OK
Date, Boolean, Number等: nullとして設定されるべき。ただし、Date型については結果的に無視されて(※)、ドメインに設定されない。Date型については要対処★
※ パース例外が発生し、かつ、値が空文字の場合にはtypeMismatch扱いにされないため、しれっと無視されることになる(「FORMで送信されていない」と同じ挙動にみえる)
ドメイン上のプロパティにnullが設定される (convertEmptyStringsToNull=true)
String: オプション的文字列フィールド(備考欄)、などであれば空文字のまま設定されるべき。しかし、nullになる。要対処
対処例
(a) blank:falseではないStringにはnullable:trueを明示して、nullを許容する (個人的に非推奨)
(b) beforeValidateでnull->空文字補完をしてnullableエラーを回避する
Date, Boolean, Number等: nullとして設定されるべき。実際される。OK
FORMで送信されていない
そもそもドメインに設定されるべきではない。実際されない。OK
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment