エラーメッセージの国際化(1)

2009/01/09

前回は、サンプルアプリケーション asagao の Member モデルの各フィールド名を国際化しました。

今回は、その他のモデルのフィールド名について駆け足で国際化を行った後、エラーメッセージの国際化に着手します。


以下の手順で作業を行ってください。

  1. app/models ディレクトリにあるすべてのモデルクラスのソースコード(member.rb を除く)の定数 REAL_ATTRIBUTE_NAMES の記述を参考に、config/locales/activerecord_en.yml および config/locales/activerecord_ja.yml に各フィールド名の翻訳を書き写します。
  2. 上記のモデルクラスのソースコードから定数 REAL_ATTRIBUTE_NAMES とクラスメソッド real_attribute_name の定義を削除します。
  3. ruby script/humanize.rb を実行します(引数なしで)。
  4. app/views ディレクトリ以下にあるすべてのファイルを対象に、.human_attribute_name(attr.to_sym) という記述を探し、.human_attribute_name(attr) に変更します(.to_sym を削除)。
  5. rake test:functionals を実行して、失敗がないことを確認します。

real_attribute_name メソッドを使わずに直接 HTML テンプレート書き込まれているフィールドもありますので、アプリケーション全体が国際化されたわけではありませんが、とりあえず Rails 2.2 の流儀に従った書き方になりました。


次に、エラーメッセージの国際化です。

『基礎 Ruby on Rails』のオリジナルのソースコードでは、エラーメッセージが直接モデルクラスに書き込まれていました。

例えば、member.rb には次のような記述があります。

  validates_presence_of :member_number,
    :family_name, :given_name, :furigana, :login_name,
    :message => 'が記入されていません。'
  validates_length_of :family_name, :given_name, :furigana,
    :email, :phone, :login_name,
    :maximum => 60,
    :message => 'は60文字以内で記入してください。'

Rails 2.2 ではどのように記述すべきでしょうか。


まず、http://rails-i18n.org/wiki/pages/translations-available-in-rails を参照して、「ActiveRecord」と書かれた部分のコードを config/activerecord_en.ymlconfig/activerecord_ja.yml の末尾にコピーします。ただし、最初の en-US:activerecord: の行は省きます。

続いて、config/activerecord_ja.yml の各行を日本語に翻訳します。

(省略)
    errors:
      messages:
        inclusion: "は一覧にありません。"
        exclusion: "は予約されています。"
        invalid: "が不正な値です。"
        confirmation: "が一致しません。"
        accepted: "を承諾してください。"
        empty: "が記入されていません。"
        blank: "が記入されていません。"
        too_long: "は{{count}}文字以内で記入してください。"
        too_short: "は{{count}}文字以上で記入してください。"
        wrong_length: "は{{count}}文字で記入してください。"
        taken: "はすでに使用されています。"
        not_a_number: "は数値で入力してください。"
        greater_than: "は{{count}}より大きい値を指定してください。"
        greater_than_or_equal_to: "は{{count}}以上の値を指定してください。"
        equal_to: "は{{count}}を指定してください。"
        less_than: "は{{count}}より小さい値を指定してください。"
        less_than_or_equal_to: "は{{count}}以下の値を指定してください。"
        odd: "は奇数を指定してください。"
        even: "は偶数を指定してください。"
        # Append your own errors here or at the model/attributes scope.

      models:
        # Overrides default messages

      attributes:
        # Overrides model and default messages.

これらは、すべてのモデルに共通のエラーメッセージとして使用されます。

blank などのキーワードは、バリデーションメソッドに対応しています。

例えば、validates_presence_of が失敗した場合のデフォルトのメッセージは、t('activerecords.errors.messages.blank') です。

メッセージ中にある {{count}} などの記述は、そこに別の値が埋め込まれることを示しています。

この結果、先ほどの member.rb は、次のようにすっきりさせることができます。

  validates_presence_of :member_number,
    :family_name, :given_name, :furigana, :login_name
  validates_length_of :family_name, :given_name, :furigana,
    :email, :phone, :login_name,
    :maximum => 60

このように、Rails 2.2 の登場により、私たちはアプリケーションのロジック(論理)とプレゼンテーション(見え方)をより明確に分離できるようになりました。

プレゼンテーションを分離できると、アプリケーション全体で表現を統一しやすくなります。ある場面では「○○が記入されていません」と表示され、別の場面では「○○を記入してください」と表示されるのは避けたいところです。

本日はこの辺にします。次回は、モデル別、フィールド別にエラーメッセージを変える方法を説明します。