Rails I18n(日本語化)を使用する場合の躓きポイント徹底攻略(enum)

# はじめに

こんにちは！
記念すべき <font color="red">**DMM WEBCAMP mentor Advent Calendar 2022**</font> :christmas_tree: **1日目** を担当します @Keichan_15 です！

普段はDMM WEBCAMPで受講生さんの質問対応などを行うメンターとして働いております！
今回は、日頃から受講生さんの対応を行う中で特に躓きが多かった箇所である **「I18nを用いた日本語化が反映されない」** 問題を解決していこうぜ！ といった記事になります。

本記事では主に、
- **I18nって何のこと？**
- **日本語化したのに反映されないよ…**

と疑問や悩みをお持ちである、多くの方々の助けとなれれば幸いです！

また本記事が自身のQiita初執筆になりますので、多々目に余る箇所などがあるかとは思いますが温かい目で見守って頂けますと幸いです…。
よろしくお願い致します！

# 1. そもそも I18n は何ができるの？
まず I18n とは何なのでしょうか。
I18n は **internationalization** の略で、日本語でいうところの **国際化** になります。
では国際化とは何ぞや…というと、 <font color="red">**あるアプリケーション内で使用されている言語の文言を別の言語の文言に翻訳する機能** </font> (ex. 英語 → 日本語) のことです。

Railsガイドにおいても以下のように解説されています。
> RubyのI18n（国際化・多言語化: internationalizationの略）gemはRuby on Rails 2.2以降からRailsに同梱されています。このgemは、アプリケーションの文言を英語以外の 別の1つの言語に翻訳 する機能や 多言語サポート 機能を簡単かつ拡張可能な方式で導入するためのフレームワークを提供します。

https://railsguides.jp/i18n.html


I18nを活用すると出来ることの一例に、下写真のようなエラーメッセージの表記を英語 → 日本語に変更することができます！
※執筆時間の関係上、モデル部分(Title, Body)の日本語化は省略しています。


- I18n 適用**前**
![2022-12-01 (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2798073/7e8c1ccf-a1c6-d2df-937f-e17050c11073.png)
- I18n 適用**後**
![2022-12-01 (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2798073/7615078e-57ce-2d4d-50ac-e8cd2722dfd3.png)

日本語にエラーメッセージを翻訳できると、開発するWebアプリケーションのユーザビリティの向上にも繋がるので、I18nをバンバン活用していくことをお勧めします！

I18nの概要について把握できたところで本題に入っていきましょう！

# 2. 日本語化が反映されない…ナゼ？
実際に受講生さんからご質問を頂くケースで頻出だったのが、
**「日本語化が反映されないんです。なぜですか…。」**
というものでした。

対応を重ねる中で、考えられる要因について分析した結果、以下 **3つ** の原因によるものが多いのではないか？という結論に至りました。
段階を追って原因を一緒に探していきましょう！

## 2.0 前提
今回は簡単なアプリケーションを例に用いて、原因について順に見ていこうと思います。

![2022-12-01 (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2798073/0cdb9630-d9f2-04a9-3ef5-45bc16862e45.png)

画像内で `支払方法 credit_card` の **`credit_card`** となっている部分を  **`クレジットカード`** に変更したい！という場合を想定します。
また、表示するViewは `confirm.html.erb` である場合を想定します。適宜ご自身のViewに置き換えてください。

## 2.1 日本語化、それ本当に入ってる？
まず第一に考えられる原因として、 **configファイルに日本語化の設定を行うための記述に漏れがある** パターンです。
日本語化を行うためにはこの設定が **必要不可欠** です！

```ruby:config/application.rb
module ご自身のアプリケーション名
  class Application < Rails::Application
    # Initialize configuration defaults for originally generated Rails version.
    config.load_defaults 6.1

    # Configuration for the application, engines, and railties goes here.
    #
    # These settings can be overridden in specific environments using the files
    # in config/environments, which are processed later.
    #
    # config.time_zone = "Central Time (US & Canada)"
    # config.eager_load_paths << Rails.root.join("extras")
    config.i18n.default_locale = :ja
  end
end
```

ここでのconfigファイル内に記述のある、

```ruby:config/application.rb
    config.i18n.default_locale = :ja
```
**この1行、漏れてないでしょうか…？**
導入段階で記述漏れがある場合が多いので、まずはしっかりと確認してみましょう！

それでも解決しないよ…という方々、まだ打開できる策はご用意しています！
次のパターン、いってみましょう！

## 2.2 末尾にI18n付け忘れてない？
次のパターンも比較的シンプルな原因です。
 **日本語化したいコードの末尾に「_i18n」の表記漏れがある** パターンです。


```erb:confirm.html.erb
...
  <div class="row">
    <p>
      <strong>支払方法</strong>
    </p>
    <p>
      <%= @order.payment_method %>
    </p>
  </div>

  <div class="row">
    <p>
      <strong>お届け先</strong>
    </p>
    <p>
      <%= @order.address_display %>
    </p>
  </div>

...
```

ここでは日本語化させるコードを
```erb:confirm.html.erb
<%= @order.payment_method %>
```
とします。

現状の記述のままでは、 `<%= @order.payment_method %>` には日本語化する前のデータである `` 'credit_card' `` が入っています。
この `` 'credit_card' `` を日本語化するには、コードの末尾に **_i18n** の記述を追加してあげましょう！

```erb:confirm.html.erb
...
  <div class="row">
    <p>
      <strong>支払方法</strong>
    </p>
    <p>
      <!-- 末尾に_i18nを付けて日本語化！ -->
      <%= @order.payment_method_i18n %>
    </p>
  </div>

  <div class="row">
    <p>
      <strong>お届け先</strong>
    </p>
    <p>
      <%= @order.address_display %>
    </p>
  </div>
```

![2022-12-01 (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2798073/b8463437-103e-c0bc-6528-5f44b4459891.png)

ちゃんと日本語に翻訳されて表示されましたね！:relaxed:

ただ、それでもまだ日本語化されないよ…とお悩みの方、 <font color="red">**まだ諦めるのは早いです！！**</font> 

実は最後にお伝えするパターンが、反映されない問題のほとんどを担っているのではないかと思います！一緒に見ていきましょう！

## 2.3 ymlファイルを見るんだ！今すぐに！！
自身の体感上ですが、日本語化されない原因の9割以上は **ymlファイル** に問題があります。

今回は、例で紹介したアプリケーションを日本語化するために `ja.yml` を作成し、そのファイル内に日本語化するための記述を行っていると仮定します。



``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"
```

ここで重要なのはズバリ **インデント** になります！

インデントのずれはymlファイルにとって **死** を意味します。大袈裟みたいに聞こえますけどね…笑

以下、NG例をコードを交えて紹介します。

### NG例①
**:o: OKパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"
```

**:x: NGパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
    payment_method:
      credit_card: "クレジットカード"
      transfer: "銀行振込"
```

ここでのNGポイントは、

``` yml:config/locales/ja.yml
    order:
    payment_method:
```
`order:` と `payment_method` のインデント位置が **同じ位置にある** 点です。

ymlファイルの特徴の1つに **階層構造** の仕組みがあります。
これはインデントを活用してデータの階層構造を表現する仕組みで、 **1つでもインデントがずれてしまうと** 実行時にエラーが生じることがあります！

RailsでViewの実装を行う際、一般的には `erb` ファイルに記述を追加していく流れになるかと思います。 `erb` ファイルはインデントに多少のずれがあっても挙動に問題無いことが多いですが、 `yml` ファイルは許してくれません。

### NG例②
``` yml:config/locales/ja.yml
ja:
  enums:
    order:
      credit_card: "クレジットカード"
      transfer: "銀行振込"
```

ここでのNGポイントは、 **必要な記述に漏れがある** 点です。
OKパターンとNGパターンのコードを見比べてみると、

**:o: OKパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"
```

**:x: NGパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      credit_card: "クレジットカード"
      transfer: "銀行振込"
```

``` yml:config/locales/ja.yml
    payment_method:
```
の一行が抜けてしまっていますね。
このように書いたつもり…であっても再度確認してみると記述漏れがあることも多いので、しっかり確認してみましょう！

### NG例③

**:o: OKパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"
```

**:x: NGパターン**
``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"
```

**ん？一緒じゃない？？** って思われた方、仰る通りです。笑

実は第3の原因として考えられるのが、 **インデントを整える際に "Tabキー" を使用している** パターンです。
インデントを整える際はTabキーでは無く、必ず **半角スペース** を使用しましょう。
…ということなのですが、執筆者はTabキーでも問題無く反映されています。
この違いは何なのでしょうか…。有識者の方がいらっしゃいましたら是非ともコメント頂けますと幸いです。

ちなみに執筆者は前述から分かるように、インデントを整える際はどちらかというとTabキー派なので、これを発見した時は驚きました…。
※インデントは スペースで整える派 or Tabキーで整える派 の派閥争いのお話はここでは控えます。終わり見えないですから…。

### NG例④ ※2022/12/28追記
先日、受講生様の環境にて新たなパターンを発見致しました。自身の環境下でも同様の挙動になることを確認済のため、共有します！

**:x: NGパターン**

``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"

ja:
  times:
   ~~ 以下省略 ~~
```

ここでの :x: NGポイントは **ja.yml内に `ja:` の記述が重複して記述されている** 点です。

上記の例のように、同一ファイル内に `ja:` の記載が2つ以上あると、ja.ymlが正しく読み込まれず、英語表記のままの状態になります。

例に出すパターンですと、enumの日本語化だけでなく、別の箇所も同時に日本語化をしたい！となる際に記述してしまうパターンが多いのではないかと推測します。

**:o: OKパターン**

``` yml:config/locales/ja.yml
ja: 
  enums:
    order:
      payment_method:
         credit_card: "クレジットカード"
         transfer: "銀行振込"

# ----- ja: の記述は1つで良いヨ！ ------ #
# ja:
# ----- コメントアウトするか消してあげてね！ ------ #

  times:
   ~~ 以下省略 ~~
```

ここで抑えて頂きたいポイントはズバリ！ **`ja:` の記述は1つだけ！！** ですね！
受講生さんの鋭い着眼点に、自分も勉強になりました。ありがとうございます！:relaxed:

# おわりに
今回はRailsで I18nを使用する場合の躓きポイントについて紹介しました。いかがでしたでしょうか。
本記事で紹介した I18n はほんの一部分に過ぎません。自身も執筆する中でより I18n について理解が深まりました。
少しでもこの記事を読んで頂いた方のお役に立てれば幸いです。是非とも素敵な I18n ライフをお過ごしください！:airplane:
最後までお読みいただき、ありがとうございました～！