【Rails】i18n で日本語化する方法

目次

はじめに

i18nというデフォルトでRailsに同梱されているgemを使ってRailsアプリを日本語化しました。

ここでいう日本語化というのは、ビューファイルには日本語を記述せずにブラウザ上の表示は日本語になっていることを指します。

具体例を手を動かしながら進めると理解の助けになるかと思います。

実装

実装手順は大まかに次の通りです。

  1. Railsのアプリケーション設定
  2. (モデルとコントローラー、ビューを作成)
  3. 辞書ファイルの作成( ja.yml )
  4. ビューを辞書から参照するように書き換える

Railsアプリを新しく作成します。

$ rails new i18n_practice

Railsのアプリケーション設定

config/application.rbにデフォルトで日本語の辞書を読み込むように設定します。また、読み込む辞書ファイルをconfig/locales/配下の全てのrb, ymlファイルに設定します。

次の2行を追加します。

config.i18n.default_locale = :ja
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
require_relative 'boot'

require 'rails/all'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(*Rails.groups)

module I18nPractice
  class Application < Rails::Application
    config.load_defaults 5.2

    config.i18n.default_locale = :ja
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]

  end
end

モデルとコントローラー、ビューを作成

モデルとコントローラーを作成します。

$ rails g model user name:string email:string password:string
...
$ rails g controller users index new
...

テーブルを作成します。

$ rails db:migrate

ルーティング設定とビューを編集します。

ルーティングにルートへのアクセスを追加し、あとでform_withヘルパーを使うときに楽なのでリソースルーティングにします。

Rails.application.routes.draw do
  root 'users#index'
  resources :users, only: %i[index new]
end

ビューを次のように編集します。

<h1>Users#index</h1>

<p>インデックス</p>
<p>サッカー</p>
<p>銀行</p>

<%= form_with model: @user, local: true do |form|  %>
  <div>
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :email; %>
    <%= form.email_field :email %>
  </div>
  <div>
    <%= form.label :password %>
    <%= form.password_field :password %>
  </div>
  <div>
    <%= form.submit '送信' %>
  </div>
<% end %>

<div><%= link_to 'new', new_user_path %></div>
<h1>Users#new</h1>

<p>新しい</p>
<p>野球</p>
<p>川岸</p>

<%= form_with url: "#", local: true do |form|  %>
  <div>
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :email; %>
    <%= form.email_field :email %>
  </div>
  <div>
    <%= form.label :password %>
    <%= form.password_field :password %>
  </div>
  <div>
    <%= form.submit '送信' %>
  </div>
<% end %>

<div><%= link_to 'index', users_path %></div>

現時点での表示は次の通りです。

f:id:aoshota:20201003115016p:plain
コードに日本語を記述しているindexビュー
f:id:aoshota:20201003115221p:plain
コードに日本語を記述しているnewビュー

コードを見てわかるように今は直接日本語をコードに書いています。これをi18nを使ってコードに日本語は書かず、辞書ファイルを用意することにより同じ表示を実装します。

辞書ファイルの作成( ja.yml )

辞書ファイルを作成します。辞書ファイルはconfig/locales配下に配置します。

デフォルトでconfig/localesにen.ymlがありますがこれは使わないので削除します。

config
└── locales
   ├── activerecord
   │   └── ja.yml
   └── views
       └── ja.yml

lazy lookup記法で簡潔に辞書ファイルを記述することができます。

activerecord/ja.ymlにはモデルに関連することを記述しviews/ja.ymlにはビューに関連することを記述します。

モデルに関する辞書を読み込むことでform_withヘルパーなどでモデルのインスタンス変数を渡した際に自動で紐つけて日本語化してくれます。

ja:
  activerecord:
    models:
      user: ユーザー
    attributes:
        user:
          id: ID
          name: 名前
          email: メールアドレス
          password: パスワード
  attributes:
    created_at: 作成日
    updated_at: 更新日

コントローラーやアクションを越えて使うような単語はdefaultsなどにまとめて設定すると便利です。

ja:
  defaults:
      send: 送信
  users:
    index:
      index: インデックス
      soccer: サッカー
      bank: 銀行
    new:
      new: 新しい
      baseball: 野球
      bank: 川岸

ビューを辞書から参照するように書き換える

i18nのtranslateメソッドを使うことにより辞書を読みんで多言語化することができます。

埋め込みRubyでは次のように実装します。

<%= translate '.title' %>

translateメソッドは省略することもできます。

<%= t '.title' %>

今回のビューファイルは次のように書き換えることができます。

form_withヘルパーにモデルのインスタンス変数を渡している場合はモデルに関する辞書を自動に読み込んでくれます。

<h1>Users#index</h1>

<p><%= translate '.index'  %></p>
<p><%= t '.soccer' %></p>
<p><%= t '.bank' %></p>

<%= form_with model: @user, local: true do |form|  %>
  <div>
    <%= form.label :name %>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :email; %>
    <%= form.email_field :email %>
  </div>
  <div>
    <%= form.label :password %>
    <%= form.password_field :password %>
  </div>
  <div>
    <%= form.submit (t 'defaults.send') %>
  </div>
<% end %>

<div><%= link_to 'new', new_user_path %></div>

form_withヘルパーにURLを渡している場合、明示的にモデルを指定することにより読み込む辞書を判断してくれます。

<h1>Users#new</h1>

<p><%= translate '.new' %></p>
<p><%= t '.baseball' %></p>
<p><%= t '.bank' %></p>

<%= form_with url: "#", local: true do |form|  %>
  <div>
    <%= form.label :name, User.human_attribute_name(:name) %>
    <%= form.text_field :name %>
  </div>
  <div>
    <%= form.label :email, User.human_attribute_name(:email) %>
    <%= form.email_field :email %>
  </div>
  <div>
    <%= form.label :password, User.human_attribute_name(:password) %>
    <%= form.password_field :password %>
  </div>
  <div>
    <%= form.submit (t 'defaults.send') %>
  </div>
<% end %>

<div><%= link_to 'index', users_path %></div>

これでコードに日本語表記はないですが、ブラウザの表示は日本語化されています。

f:id:aoshota:20201003130002p:plain
コードに日本語表記がないindexビュー
f:id:aoshota:20201003130039p:plain
コードに日本語表記がないnewビュー

まとめ

辞書ファイルを作成しビューのコードに直接日本語を記述しない方法を実装しました。

用途に沿ってファイル分割をすることにより可読性もメンテナンス性も上がると思います。

なので、なるべく日本語化(多言語化)は辞書ファイルから読み込む方法で実装するべきだと感じました。

rails-i18nといったgemを使うと一般的な用語(エラーや単位など)は多数の言語に対応できるようなので時間があるときに触ってみたいと思います。

終わりに

最初は理解が難しかったですが手を動かしているうちに理解できるようになりました。

Railsの便利さには日々驚かされます。

参考文献