ActiveRecord::Errorsあたりのローカライズ

このサイトを参考にしました。というより全くこの通りにやりました。

validate_関連で、エラーが出た際にいろいろ英語がでてきちゃうのでその辺りを修正。まずは、フォームのエレメント名がそのままでちゃうのを防ぐために、modelの中で、下記のようにローカライズ

class Member < ActiveRecord::Base
  class << self
    HUMANIZED_ATTRIBUTE_KEY_NAMES = {
      "email"     => "メールアドレス",
      "password"  => "パスワード",
      "nickname"  => "ニックネーム",
      "gender"    => "性別",
    }

    def human_attribute_name(attribute_key_name)
      HUMANIZED_ATTRIBUTE_KEY_NAMES[attribute_key_name] || super
    end
  end

それから、"email is blank."とか出てくる" is blank"とかのメッセージをローカライズ。これは個々のvalidate_...でmessagesを指定すれば良いのだけど、毎回やるのはDRYじゃないので、まとめて設定。environment.rbの中に下記のように設定

ActiveRecord::Errors.default_error_messages[:inclusion]    = "が選択肢にありません" 
ActiveRecord::Errors.default_error_messages[:exclusion]    = "が予約されています" 
ActiveRecord::Errors.default_error_messages[:invalid]      = "が不正です" 
ActiveRecord::Errors.default_error_messages[:confirmation] = "が確認内容があっていません" 
ActiveRecord::Errors.default_error_messages[:accepted]     = "が許可されていません" 
ActiveRecord::Errors.default_error_messages[:empty]        = "が入力されていません" 
ActiveRecord::Errors.default_error_messages[:blank]        = "が入力されていません" 
ActiveRecord::Errors.default_error_messages[:too_long]     = "が長すぎます(最長%d文字)" 
ActiveRecord::Errors.default_error_messages[:too_short]    = "が短すぎます(最短%d文字)" 
ActiveRecord::Errors.default_error_messages[:wrong_length] = "が間違った長さです(長さ%d文字)" 
ActiveRecord::Errors.default_error_messages[:taken]        = "が既に使われています" 
ActiveRecord::Errors.default_error_messages[:not_a_number] = "が無効な数値です"

これでもまだ、エラーメッセージ全体を表示する<%=error_messages_for '...' %>の部分で英語がでてくるので、これの変わりになるヘルパーを作成。app/helpers/application_helper.rbの中に下記を追加

def template_error_messages_for (object_name, options = {})
  options = options.symbolize_keys
  object = instance_variable_get("@#{object_name}")
  unless object.errors.empty?
    render :partial=>"system/error_messages_for",
      :locals=>{:messages=>object.errors.full_messages, :object=>object}
  end
end

で、上で使うpartialを作成する。app/views/system/_error_messages_for.rhtmlとして、下記のように作成。mobile on railsを使っている場合はapp/views/views_mobile/system/_error_messages_for.rhtmlも作成する

<div class="errorExplanation" id="errorExplanation">
  <h2><%= messages.size %>個のエラーが発生しました</h2>
  <p>次の項目に問題があります</p>
  <ul>
    <% for mes in messages %><li><%= mes %></li><% end %>
  </ul>
</div>

あとはローカライズではないけど、エラーが出たときにフォームフィールドが<div class="fieldWithErrors">で囲まれてしまう問題を回避する。

が入ると改行が入ってしまうので携帯ブラウザでの表示に困る(cssで対応できない場合)。これはenvironment.rbに下記を追加

ActionView::Base.field_error_proc = lambda{|tag, instance| "<span class=\"fieldWithErrors\">#{tag}</span>" }

今日のrailsはこんな感じ。しかし検索で見つけ出した対応策が2005-08-02付けとかだったらしたら、もうobsoleteだろうとか思って不安になってくる。一応コードを試すとちゃんと動くんだけど、実際にはもっとスマートなやり方があるんじゃないかとか。まぁそういうのは使っていくうちに気づくだろう。