長年の課題
Railsには標準で日付のフォーマットのバリデーションがありません。
これまで正規表現でチェックしたりgemを使ったりjavascript側でやったりと色々と試行してきたのですが……
解決策
最終的にベターな方法としてDate.parseを使う方法に落ち着きました。
これなら"2017-9-1"や"2017/09/01"、はたまた"20170901"のようなフォーマットにもゆるく対応できます。JQueryカレンダー入力にも。
model/concern/date_validator.rb
class DateValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
value = record.send("#{attribute}_before_type_cast")
begin
Date.parse value if value.present?
rescue ArgumentError
record.errors[attribute] << I18n.t('errors.messages.invalid')
end
end
end
model/user.rb
...
validates :birthday, date: true # 誕生日
まとめ
しかしメタプログラミングやら例外を使っているので、どうしてもバッドノウハウ感が拭いきれません。
HTML5の日付入力欄が普及してくれれば、こんなことはブラウザ側に任せてしまいたいですね。