nilを許容で、値がある場合にformatのバリデーションをかけたいのですが、formatにそってない値の場合、saveの際に全てnilに変換されて、通ってしまいます。
saveを通さずにバリデーションで警告したいのですが、
いい方法があればご教示下さい。
下記Gistに貼ったような事を試しましたが、どちらもformatに合わない値はnilに勝手に変換されてsaveされてしまいます。
https://gist.github.com/chucker34/f1c9f8d3d3dda7d6ba02
https://gist.github.com/chucker34/b783c95ebab0fecdbbc7
環境は下記です。
ruby '2.1.2'
rails'4.1.4'
宜しくお願いします。
Ruby on Rails の String#to_date の実装の実装がこんな感じです。
# File 'activesupport/lib/active_support/core_ext/string/conversions.rb', line 43 def to_date ::Date.parse(self, false) unless blank? endClass: String — Documentation for rails (4.0.0)
irb とかで試してみれば分かりますが、Date#parse は、自由度が かなり高いです。
さすがに 'a' とか渡すと例外が出ますが、'190' なんかでは、きちんと(?)parse してくれちゃいます ><
つまり、質問の二番目の実装では、例外が出ないので rescue に制御が渡らない...
試してませんけど、こんな感じでバリデータを実装してみたらどうでしょうか。
class DateValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) unless value.blank? and /\A\d{4}\-\d{2}\-\d{2}\Z/ =~ value record.errors[attribute] << (options[:message] || "2015-01-01の形式で入力してください") end end end