Railsに国際化(i18n)を導入したので振り返り

はじめに

Railsでは、言語の文字列に対して翻訳済みの値を定義することでローカライズを行います。

RailsではI18nモジュールがあり、この中のメソッドを利用するのが一般的です。

I18n APIで最も重要なメソッド

translate # 訳文を参照する
localize  # DateオブジェクトやTimeオブジェクトを現地のフォーマットに変換する

上記の二つは以下のように省略可能です。

I18n.t 'hello'  # => "Hello world"
I18n.l Time.now # => "Thu, 15 Oct 2020 15:23:04 +0900"

デフォルトではen.ymlがconfig/localにあるので中身を見てみると

en:
  hello: "Hello world" 

先程のI18n.t 'hello'がここを参照しているのが分かります。

日本語訳してみる

before Image from Gyazo Image from Gyazo

上記2つを日本語訳していきます。

モデル名や各カラムに対する日本語訳を config/locales/activerecord/ja.yml
viewに対する日本語訳を config/locals/views/ja.yml
に書いていきます。

Image from Gyazo

config/application.jsの設定

まずは、デフォルトのロケール(英語)を日本語に変更します。

config.i18n.default_locale = :ja

次にPATHを設定を行います。デフォルトではconfig/locales下の.rb.ymlしか参照しません。
それより深い階層も参照するには以下の設定を行います。

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

これらをconfig/application.jsに追加します

config/application.rb

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

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


    config.generators.system_tests = nil
  end
end

Active Recordモデルで翻訳を行う。

ユーザー登録画面ではform_withメソッドを使用し、modelオプションにUserモデルのインスタンスを渡しています。(@user = User.new)
Image from Gyazo

この場合はActive Recordモデルを使用して翻訳を行ないます。

config/locales/activerecord/ja.yml

ja:
  activerecord:  #<= active_recordを使用することを宣言
    models:
      user: "ユーザー"
    attributes:
      user:
        last_name: ""
        first_name: ""
        email: "メールアドレス"
        password: "パスワード"
        password_confirmation: "パスワード確認用"

属性名を参照するメソッドはModel.human_attribute_name(attribute)です。 rails console で確かめると

> User.human_attribute_name(:email)
=> "メールアドレス"   # <= うまく設定できている!!

Modei名を参照する場合は

User.model_name.human
=> "ユーザー"

Image from Gyazo

viewテンプレートに対して翻訳を行なう

ログイン画面のviewは以下のようになっています。
新規登録の画面と違い、モデルのインスタンスを使用していません。

Image from Gyazo

上記のファイルまでのpathはapp/views/sessions/new.htm.erbとなっています。

lazy lookup

controller、view内でロケールを参照する際に便利な方法がlazy lookupです。
これはディレクトリの階層を翻訳ファイルで設定することで、参照するキーを短縮して書くことができます。

config/locales/views/ja.yml

ja:
  sessions:  # <= app/views/sessions と sessions_controllerを指します
    new:  # <=  一階層下のnew.html.erb と sessions#newを指します。
      email: "メールアドレス"
      password: "パスワード"

設定後、new.html.erbを変更します。

<%= f.label :email %>
<%= f.label :password %>
<!-- 下記に変更する -->
<%= f.label :email, (t 'sessions.new.email') %>
<%= f.label :password, (t 'sessions.new.password') %>

ファイルの階層と翻訳ファイルの階層が合っているほど、キーを省略できます。

<%= f.label :email, (t '.email') %>
<%= f.label :password, (t '.password') %>

もしくは先程のactiverecordを利用して以下のようにも書けます。

 <%= f.label :email, User.human_attribute_name(:email) %>
 <%= f.label :password, User.human_attribute_name(:password) %>

Image from Gyazo

テンプレートをダウンロードする

英語から日本語によく翻訳されるワードに関しては、github上にテンプレートとして公開されています。

Gemfileに下記を追加してください。

gem 'rails-i18n'

もしくは

rails-i18n/ja.yml at master · svenfuchs/rails-i18n · GitHub

これをアプリケーションに取り込んでみます。

 curl -s https://raw.githubusercontent.com/svenfuchs/rails-i18n/master/rails/locale/ja.yml >> config/locales/ja.yml    

無事に読み込まれていれば完了です。

参考

Rails 国際化 (i18n) API - Railsガイド

【Rails】I18n入門書 | Pikawaka - ピカ1わかりやすいプログラミング用語サイト