Rails多言語化メモ

Railsの多言語化を行うため、rails-i18ngemを入れる。バージョンはRailsのバージョンごとに指定を変更する。

詳細はhttps://github.com/svenfuchs/rails-i18nを参照。

gem 'rails-i18n', '~> 6.0.0'

デフォルトのロケールを日本語に変更する

config/initializers/i18n.rbファイルを以下の内容で作成する。

I18n.default_locale = :ja

ActiveRecordモデルの多言語化

config/locales/ja.ymlに以下のような形で追加していく(ファイル名は任意)。

ja:
  activerecord:
    models:
      feed: フィード
      feed_url: フィード取得元URL
    attributes:
      feed:
        title: タイトル
      feed_url:
        category: カテゴリ

Feed.model_name.humanFeed.human_attribute_name(:title)のようにすることで対応する訳語を取得できる。

ActiveModelモデルの多言語化

config/locales/ja_active_model.ymlに以下のような形で追加していく(ファイル名は任意)。

ja:
  activemodel:
    models:
      some_model: モデル名
    attributes:
      some_model:
        title: タイトル

SomeModel.model_name.humanSomeModel.human_attribute_name(:title)のようにすることで対応する訳語を取得できる。

SomeModule::SomeModelのような階層構造になっている場合は、以下のようにする。

ja:
  activemodel:
    models:
      some_module/some_model: モデル名
    attributes:
      some_module/some_model:
        title: タイトル

ロケールの適用

コントローラーなどでI18n.locale = :enのように指定することができるが、クラスインスタンス変数に保持しているため他のリクエストが影響を受ける可能性がある。

例えば、I18n.default_locale = :jaとなっている状態で、以下のアクションがあるとする。

  def index
    # ...
  end

  def new
    # ...
    I18n.locale = :en
  end

このとき、newアクションを処理したワーカーは再起動されるまで:enのロケールで処理される。

5スレッドワーカーが起動している状態で2つのワーカーでnewアクションを処理したとすれば、3つのワーカーはindexアクションの結果を日本語で出力し2つのワーカーはindexアクションの結果を英語で返す状態になる。

したがってI18n.locale=を使うならば、すべてのコントローラーで漏れなく確実に指定しなければならないし、I18n.locale=ではなくI18n.with_localeを使うことが推奨される。I18n.with_localeを使えばブロック内にのみ指定したロケールが適用され、上記のような問題が発生しない。

class ApplicationController < ActionController::Base
  around_action :switch_locale

  def switch_locale(&action)
    # 適当な方法でロケールを取得する(以下の例はクエリパラメータで指定されることを想定)
    locale = params[:locale] || I18n.default_locale
    I18n.with_locale(locale, &action)
  end
end