Site cover image
Ruby on Rails カスタムバリデーションのエラーメッセージを翻訳する

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の翻訳を追加する方法を説明しました。

Thank you!
Thank you!
URLをコピーしました

コメントを送る

コメントはブログオーナーのみ閲覧できます