【Rails】I18nを使用した多言語対応(日本語化)

はじめに

Ruby on Railsのデフォルトの言語は英語です。デフォルト言語が英語ということで一番初めに困るのは、エラーメッセージが英語で表示されることでしょう。バリデーションエラーにより表示されたメッセージが英語だと、とてもユーザーフレンドリーなアプリケーション設計とはいえません。

Railsには、このようなエラーメッセージを多言語化(もちろん日本語化も)する機能があります。エラーメッセージ以外にも、例えばビューで使用する文字列なども簡単に変換することができます。

本記事では、I18nを使用した多言語対応についてまとめています。

I18nについて

I18nとはRubyのGemのひとつで、「Internationalization(国際化)」の略記です。Rails 2.2から標準同梱されているのでインストールすることなく使えます。

Railsアプリの日本語化

手っ取り早くRailsアプリを日本語化したいだけなら、次の手順を行います。

config/application.rbに以下を追記します。Railsアプリのデフォルト言語を英語(en)から日本語(ja)に変更します。これにより、ロケールファイルのうち、ja配下の翻訳が使用できるようになります。また、config/locales/ディレクトリ配下の拡張子がrbまたはymlのファイルをロケールファイルとして追加します。

module ApplicationName
  class Application < Rails::Application
    # 以下を追記
    config.i18n.default_locale = :ja
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
  end
end

rails-i18nのGitHubから日本語のロケールファイルをダウンロードし、config/locales/ディレクトリに配置します。

config
 |-locale
    |-en.yml
    |-ja.yml   # 追加

以上で日本語化対応は完了です。バリデーションのエラーメッセージなどが日本語されていることを確認してください。

I18nの使い方

ロケールファイルの形式

I18nのロケールファイルでは、Ruby形式(rb)とYAML形式(yml)2種類のファイル形式をサポートしています。どちらの形式で書いても構いませんが、書き方が若干異なるので注意が必要です。

Ruby形式(rb)の書き方は以下の通りです。

{
  ja: {
    article: {
      title: 題名,
      content: 内容
    }
  }
}

YAML形式(yml)の書き方は以下の通りです。

ja:
  article:
    title: 題名
    content: 内容

見て分かる通り、{}を書かなくて言い分、YAML形式のほうが簡単に書けます。Railsにデフォルトで用意されている英語のロケールファイルもYAML形式で書いてあるので、自分でロケールファイルを作成するときもYAML形式で書くのがいいかと思います。

なお、新しいロケールファイルを追加した場合はサーバーを再起動する必要があります(追記の場合は不要)。

ロケールファイルの書き方

ロケールファイルの基本的な書き方は、階層ごとにインデントを足していくだけという非常にシンプルなものですが、特別な階層名を使用することでより便利に使うことができます。なお、以下の分け方は独断によるものなので、公式見解とは異なる可能性があります。

ビューの翻訳

日本語の識別子jaの次の階層をコントローラー名、次の階層をビューのファイル名とし、その次の階層にビュー内で使用する文字列の翻訳を書きます。ビュー内ではスコープを省略して翻訳を呼び出すことがでるようになります。以下の例だと、articles/index.html.erb内ではt(".title")のように呼び出すことができます。

ja:
  articles:
    index:
      title: 題名
      content: 本文

モデルの翻訳

日本語の識別子jaの次の階層をactiverecordとし、modelsの下にモデル名、attributesの下にモデル名とカラム名の翻訳を書きます。このような翻訳は特別な識別子で呼び出すことができるようになります。以下の例だと、モデル名はArticle.model_name.human、カラム名はArticle.human_attribute_name(:title)で呼び出すことができます。

なお、カラム名の次の階層にカラムの値を書いても、特別な識別子で呼び出せるようになるわけではありません。

ja:
  activerecord:
    models:
      article:  記事
    attributes:
      article:
        title: 題名
        content: 本文

エラーメッセージの翻訳

I18nはエラーメッセージの翻訳をロケールファイルの中から以下の優先度で探索します。最も優先度の低い翻訳も見つからなければデフォルト(英語)のエラーメッセージが表示されます。

1. activerecord.errors.models.[model_name].attributes.[attribute_name]
2. activerecord.errors.models.[model_name]
3. activerecord.errors.messages
4. errors.attributes.[attribute_name]
5. errors.messages

rails-i18nの日本語のロケールファイルにはactiverecord.errors.messageserrors.messagesが含まれています。特定のモデルのバリデーションでこれらの翻訳を使用したくないという場合、それより優先度の高いactiverecord.errors.models.[model_name].attributes.[attribute_name]などの翻訳を追加する必要があります。

タグを含む翻訳

翻訳にタグを含めることができます。末尾に_htmlのついたキーと、htmlというキーの翻訳に含まれるタグはビューでそのまま描画されます。タグも文字列として描画したいならrawキーワードを使います。

ja:
  articles:
    title_html: <h1>題名</h1>
    content:
      html: <b>本文</b>
<%= t("articles.title_html") %>
<%= t("articles.content.html") %>

<%= raw(t("articles.title_html")) %>
<%= raw(t("articles.content.html")) %>

改行を含む翻訳

翻訳に改行を含めるには以下のように記述します。

ja:
  articles:
    content: |
      本文1行目
      本文2行目

# または

ja:
  articles:
    content: >
      本文1行目
      本文2行目

次に、以下のように翻訳を呼び出します。

<%= simple_format(t("articles.content")) %>

また、上記の「タグを含む翻訳」セクションで説明した通り、<br />タグを使うことでも改行することができます。

ja:
  articles:
    content_html: "本文1行目<br />本文2行目"

翻訳の呼び出し

ロケールファイルの翻訳を呼び出すには、I18n.tメソッドとI18n.lメソッドを使うか、Railsのヘルパーメソッドtメソッドとlメソッドを使うことができます。

ビューの呼び出し

ビューでロケールファイルの翻訳を呼び出すには以下のように記述します。

<%= t("articles.index.title") %>

ビューarticles/index.html.erb内で上記を呼び出す場合、以下のようにスコープを省略して書くこともできます。

<%= t(".title") %>

モデルの呼び出し

モデルでロケールファイルの翻訳を呼び出すには以下のように記述します。

@model = Article.model_name.human
@column = Article.human_attribute_name(:title)

以下のようにスコープを使った書き方でも呼び出すことができます。

@model = I18n.t("activerecord.models.article")
@column = I18n.t("activerecord.attributes.article.title")

正直、どちらの書き方でも長さはそんなに変わりません。特別な呼び出し方を用意するのならもう少し短い名前にしても良かったんじゃないかと思います(特にhumanが謎)。

日付/時間の呼び出し

日付/時間を現地のフォーマットに変換したい場合、以下のように記述します。

<%= l(Time.now) %>

formatオプションで長い日付/時間形式や短い日付/時間形式を呼び出すこともできます(何も指定しなければデフォルト)。

<%= l(Time.now, format: :long) %>

日付/時間でフォーマットの翻訳を記述しておく必要があります。

ja:
  time:
    formats:
      default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
      long: "%Y/%m/%d %H:%M"
      short: "%m/%d %H:%M"

まとめ

デフォルト言語を日本語に設定し、日本語のロケールファイルを用意するだけでRailsアプリの日本語化はできてしまいます。しかし、開発を進めているとそれだけでは不十分となってきて、自分でロケールファイルを書く必要が出てきます。ロケールファイルは自由に書くこともできますが、一定のルールを覚えておくとより便利に書くこともできます。

本記事を参考にして、Railsアプリの多言語対応(日本語化)を行っていただければと思います。

関連記事

【Rails】Paranoiaを使用した論理削除(ソフトデリート)
# はじめに Paranoiaは、Railsアプリケーションで論理削除(ソフトデリート)を実現するためのGemです。 論理削除は、データベースのレコードを物理的に削除するのではなく、削除フラグを設定することで「削除済み」とみなす方法です。こ [...]
2024年7月20日 21:33
【Rails】activerecord-multi-tenantを使用したマルチテナントアプリケーションの作成
# はじめに マルチテナントアプリケーションでは、複数の顧客(テナント)が同じアプリケーションを利用するため、データの分離が必要です。 activerecord-multi-tenantは、このようなマルチテナント環境をサポートするための便 [...]
2024年7月18日 16:50
【Rails】RubyとRailsにおけるattr_reader, attr_writer, attr_accessorの概念と使用方法
# はじめに RubyとRailsの開発において、`attr_reader`,`attr_writer`,`attr_accessor`は非常に便利なメソッドです。これらは、クラス内でインスタンス変数に対するゲッターおよびセッターメソッドを簡単に [...]
2024年7月17日 18:11
【Rails】RubyとRailsにおけるyieldの概念と使用方法
# はじめに RubyとRailsにおける`yield`は、メソッドやテンプレートの中で動的にコードブロックを実行する能力を提供し、これによってコードの再利用性と拡張性が大幅に向上します。本記事では、RubyとRailsにおける`yield`の概 [...]
2024年7月17日 13:15
【Rails】AASMを使用してオブジェクトの状態遷移を効率的に管理
# はじめに Railsアプリケーションにおいて、オブジェクトの状態管理は重要な課題の一つです。AASM (Acts As State Machine) gemは、複雑な状態遷移を効率的に管理します。本記事では、AASMの基本的な使い方を解説して [...]
2024年7月16日 18:00
【Rails】RSpec + Swagger + rswagでアプリケーションのAPIをテストおよびドキュメント化する方法
# はじめに Railsアプリケーションの開発において、APIのテストとドキュメント化は重要な要素です。 RSpecはテストフレームワークとして広く利用されており、SwaggerはAPIの設計とドキュメント化を支援します。これらを統合するr [...]
2024年7月16日 14:27
【Rails】mailcatcherを使用して開発環境でメール送信をテストする方法
# はじめに mailcatcherは、開発環境でのメール送信をキャプチャするためのツールです。ローカルで送信されたメールをブラウザ上で簡単に確認できるようにします。mailcatcherをRailsアプリケーションで使用する方法について説明しま [...]
2024年7月15日 16:37
【Rails】impressionistを使用してページビューやクリック数を追跡する方法
# はじめに impressionist Gemを使用してRailsアプリケーションでページビューやクリック数を追跡する方法について説明します。 # 実装方法 ## impressionist Gemのインストール まず、impre [...]
2024年7月15日 14:18