背景
仕事でvalidation warning的なものがほしいと思った。rails自体に答えを見つからなかったので、stack overflowを中心に少し調べてみた。
railsのvalidationはvalid?/invalid?の実行時あるいはインスタンスがセーブされた時にトリガーされるっぽい(Rails Guide)。validationが失敗した場合レコードをdbに保存することを止めてくれる。
今回の場合レコードをdbに保存するとともにwarningだけユーザー側へ返してほしいので、Activemodel::Errorsとにたような形でwarningにできないかを考えている。
注意
- 調べた結果が全般的に古そうなイメージがあり。何か僕の知らない一般的なやり方がすでにある、あるいは自分の考えがレアケースであり、コンベンションにそぐわないかもしれん。
- 細かく試してないのでとりあえずざっと行けそうなものをまとめてみた感じである
具体的にほしいと思う場面
- データ自体は無効ではないが、注意喚起をしたい場合。例:名前は全部大文字でよいのかとか。
- has_many associationの子を複数追加する時に一部だけ無効であり、有効なものを保存し、無効な数や原因を親に保存したいとか。
解消案
- そもそもできればクライアントサイドでそういうvalidationを解決する。サーバーサイドは最重要なvalidationのみ入れる。(*1)
- 問題点としてdb問い合わせが必要なvalidationも存在するので、クライアントサイドで全部解決できるわけではない。例えば:ユーザーが着信拒否をしているかを調べるとか
- use validation_scopes gem(*2)
- 問題点としてはwarningに使うvalidationはprivate methodを認識しないってところかな。別のvalidation classを用意すれば行けるのかな?
- WarningクラスをつくてActivemodelに追加する(※3)
- 問題点としてはActicemodelに追加するのは影響範囲が広すぎる気がするところ。でも多分部分的に追加するなどをやれば行けそうな気もする。
ちなみに
自分は最初save済みのインスタンスの.errorsに"warning"をaddすることをしていたが、こちらはvalid?に消されることに気づいた。なぜならvalid?が実際にやっているのは↓からだ。
errors.clear
run_validations!
なるほど、勉強になった。
情報ソース
*1 Soft Validation
*2 ActiveRecord - replace model validation error with warning
*3 Efficient way to report record validation warnings as well as errors?