[Ruby on Rails 4] Validator クラスを利用した Rails の Custom Validation
Validator クラスを利用して、カスタムバリデーターを適切にモデルから分離したい。
Contents
想定する利用方法
モデル内の validates に full_width_length: { maximum: 15 }
のような指定をします。
class Item < ActiveRecord::Base
validates :title, full_width_length: { maximum: 15 }
非アスキー文字を2文字としてカウントして、length をバリデーションします。
Validator クラスの置き場所
いろいろ眺めた感じでは、app/validators
を作成し、config/application.rb
にパスを加える方法が定石のようです。
ここでは app/models/concerns
に設置します。
Custom validator
このあたりを参考にします。
Ruby on Rails 4 アプリケーションプログラミング
posted with amazlet at 17.05.12
山田 祥寛
技術評論社
売り上げランキング: 19,129
技術評論社
売り上げランキング: 19,129
「5.5.5 自作検証クラスの定義」
class FullWidthLengthValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
count = count_width(value)
maximum = options[:maximum]
message = I18n.t('errors.messages.too_long', count: maximum)
record.errors[attribute] << (options[:message] || message) if count > maximum
end
private
def count_width(str)
str.length + str.chars.reject(&:ascii_only?).length
end
end
I18n による訳文の参照と追加
I18n の訳文メッセージに変数を渡す方法が分からず手間取りましたが、前述のコードの通りそのままでした。
以下のように訳文ファイルを用意します。
en:
errors:
messages:
too_long: " is too long (maximum is %{count} characters)"
ja:
errors:
messages:
too_long: " は%{count}文字以内で入力してください"
RSpec
後で書く。