Ruby on Railsでは、カスタムバリデーションを使って独自のバリデーションを追加することができます。
しかし既存のバリデーションと違い、カスタムバリデーションではi18nによる翻訳を自分で追加しなければなりません。
このエントリではRuby on Rails 5において、カスタムバリデーションのエラーメッセージerrors.full_messagesの翻訳を追加する方法を説明します。
通常、モデルのバリデーションは次のようにロケールファイルを定義しておくことでerrors.full_messagesが翻訳された状態で得られます。
ja:
errors:
messages:
blank: を入力してください
taken: はすでに存在します
full_messages:
format: "%{attribute}%{message}"
attributes:
email: メールアドレス 例えばuser.emailフィールドがpresence: trueでエラーになった場合は、blankにあたる「メールアドレス を入力してください」というエラーメッセージになります。
uniqueness: trueの場合はtakenです。
他のバリデーションと翻訳の対応は下記から探してください。
Ruby on Rails 5で独自のカスタムバリデーションを追加するためには、ActiveModel::ValidatorまたはActiveModel::EachValidatorを継承したValidatorクラスを実装します。
Ruby on Railsガイドには次のような例が載っています。
class MyValidator < ActiveModel::Validator
def validate(record)
unless record.name.starts_with? 'X'
record.errors[:name] << '名前はXで始まる必要があります'
end
end
end
class Person
include ActiveModel::Validations
validates_with MyValidator
end class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
record.errors[attribute] << (options[:message] || "はメールアドレスではありません")
end
end
end
class Person < ApplicationRecord
validates :email, presence: true, email: true
end どちらもrecord.errorsにエラーメッセージそのものを追加しています。
この方法では当然、i18nで翻訳することはできません。
errors.full_messagesを翻訳された状態で得るにはaddメソッドを使って次のようにします。
class EmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
unless value =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
record.errors.add(attribute, :not_email_format)
end
end
end addメソッドの第1引数はオブジェクトの属性です。
ActiveModel::Validatorを継承しているなら対象の属性名のシンボル(:emailや:name)としてください。
第2引数の:not_email_formatに対応する翻訳をロケールのerrorsに追加します。
ja:
errors:
messages:
blank: を入力してください
taken: はすでに存在します
not_email_format: がメールアドレスの形式ではありません このようにしておくことでEmailValidatorに引っかかったとき、errors.full_messagesが翻訳された状態で得られます。
この例ですと「メールアドレス がメールアドレスの形式ではありません」となります。
以上です。
このエントリではRuby on Rails 5において、カスタムバリデーションのエラーメッセージerrors.full_messagesの翻訳を追加する方法を説明しました。
コメントを送る
コメントはブログオーナーのみ閲覧できます