エラーメッセージの日本語翻訳（実装からエラー解決まで）

# はじめに
アプリケーションで英語エラーメッセージを日本語化する実装を行なったため、その過程及び実装中で起こったエラーとその解決を記録として残します。

# 条件
Ruby： 2.6.5
Rails： 6.0.3.6
Git： 2.30.1
Unicorn： 5.4.1

# 目次
1. 事前準備
2. エラーメッセージの日本語訳
3. 本番環境に反映
4. エラーとその解決
5. おわり

#1. 事前準備

### viewの編集
まずは、エラーメッセージ専用のviewを作成。
複数のviewで使用することを想定されているものは、別で切り出して用意しておき、呼び出すだけでいいように準備しておきます。


今回は、views / shared に`_error_messages.html.erb`ファイルを自作しました。

```
views
 └ shared
     └ _error_messages.html.erb

```
<br>
`_error_messages.html.erb`ファイルの中身

```erb:app/views/shared/_error_messages.html.erb

<% if model.errors.any? %>
  <div class="error-alert">
    <ul>
      <% model.errors.full_messages.each do |message| %>
        <li class='error-message'><%= message %></li>
      <% end %>
    </ul>
  </div>
<% end %>

```
`model.errors.any?`を記述することで、どのモデルのバリデーションにも対応できるようにします。

次に、このエラーメッセージを表示さたいviewに呼び出します。


### エラーメッセージの呼び出し

`render`を用いてエラーメッセージを表示させたい部分に、以下のように記述する。

```erb:記述例

<%= form_with model: @purchase_address, url: item_purchases_path, id: 'charge-form', class: 'transaction-form-wrap',local: true do |f| %>
    
<%# エラーメッセージの呼び出し %>
<%= render 'shared/error_messages', model: f.object %>
    

  <div class='credit-card-form'>
    <h1 class='info-input-haedline'>
      クレジットカード情報入力
    </h1>

<%# 以下省略 %>

```
これで、エラーメッセージの表示が完了。

# 2. エラーメッセージの日本語訳
### 日本語化の設定

config / application.rb 内を以下のように編集。

```ruby:config/application.rb
module アプリケーション名
  class Application < Rails::Application

    config.load_defaults 6.0

    # 日本語の言語設定
    config.i18n.default_locale = :ja

  end
end
```

続いて、`Gemfile`に`rails-i18n`というGemを導入 → ターミナルで、bundle install

```ruby:Gemfile
gem 'rails-i18n'
```
```ruby:ターミナル
bundle install
```
<b><font color="tomato">※ application.rb内に日本語の設定の記述をしていないと、Gemを導入してもに日本語で設定されないため、必ず記述。</font></b>


現段階ではまだ、ログイン / 新規登録と一部エラーメッセージが英語であるため以下の作業で完全に日本語化していく。

### localeファイル
色々な言語に対応できる言語ファイル。
ファイルは、<b>YAML</b>というファイル形式で記述する。


config / localesディレクトリに、`devise.ja.yml`ファイルを作成。

```
config
 └ locales
     └ devise.ja.yml
```
<br>
`devise.ja.yml`ファイルには、下記のサイトより記述内容を拝借して貼り付けする。
[devise-i18n/ja.yml] (https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)

```yaml:config/locales/devise.ja.yml
ja:
  activerecord:
    attributes:
      user:
        confirmation_sent_at: パスワード確認送信時刻
        confirmation_token: パスワード確認用トークン
        confirmed_at: パスワード確認時刻
        created_at: 作成日
        current_password: 現在のパスワード
        current_sign_in_at: 現在のログイン時刻
        current_sign_in_ip: 現在のログインIPアドレス
        email: Eメール
        encrypted_password: 暗号化パスワード
        failed_attempts: 失敗したログイン試行回数
        last_sign_in_at: 最終ログイン時刻
        last_sign_in_ip: 最終ログインIPアドレス
        locked_at: ロック時刻
        password: パスワード

# 以下略
```

<b><font color="tomato">※ インデントにミスがあるとエラーを起こすため、よく確認しておく。</font></b>
これで、ログイン / 新規登録のエラーメッセージの日本語化は完了。
しかしまだ一部英語が残るため、最後は手動で日本語化していく。

### ja.ymlファイルを作成

config / localesディレクトリに、`ja.yml`ファイルを作成。

```
config
 └ locales
     ├ devise.ja.yml
     └ ja.yml
```
<br>
インデントに気をつけて日本語化したい部分を記述していく。

```yaml:config/locales/ja.yml
ja:
  activerecord:
    attributes:
      user:
        nickname: ニックネーム
      item:
        name: 商品名
        description: 商品の説明
# ~ 中略 ~
# ActiveModelの場合
  activemodel:
    attributes:
      purchase_address:
        postcode: 郵便番号
        region_id: 都道府県
        city: 市区町村
        block: 番地
        phone_number: 電話番号
        token: クレジット情報
```

<br>
### テストコードを書いている場合

エラーメッセージを日本語化したため、テストコードのエラー文も英語から日本語に変換しておく。

```ruby
    context '新規登録ができない時' do
      it 'nicknameが空では登録できない' do
        @user.nickname = ''
        @user.valid?
        expect(@user.errors.full_messages).to include('ニックネームを入力してください')
      end
      it 'emailが空では登録できない' do
        @user.email = ''
        @user.valid?
        expect(@user.errors.full_messages).to include('Eメールを入力してください')
      end
      it '重複したemailは登録できない' do
        @user.save
        another_user = FactoryBot.build(:user, email: @user.email)
        another_user.email = @user.email
        another_user.valid?
        expect(another_user.errors.full_messages).to include('Eメールはすでに存在します')
      end
```
<br>
#3. 本番環境に反映

以下の記述は、<b>自動デプロイの実装を</b>行なっている程で話をしています。
変更内容はリモートリポジトリに`commit`して`push`しておく。
(ブランチを切っていたら、mergeまで実行)

```:ターミナル（EC2内）
① pemファイルがあるディレクトリに移動
% cd .ssh

② EC2にログイン
.ssh % ssh -i <鍵の名前>.pem ec2-user@ <Elastic IP>

③ 開発中のアプリケーションのディレクトリに移動
[ec2-user@ip-111-22-33-444 ~]$ cd  /var/www/開発中のアプリケーション名

⑤ GitHubからEC２へ反映
[ec2-user@ip-111-22-33-444 リポジトリ名]$ git pull origin master

④ 現在動いているプロセスの確認
[ec2-user@ip-111-22-33-444 リポジトリ名]$ ps aux | grep unicorn

ec2-user 18365  0.1 12.2 483188 123304 ?       Sl   05:11   0:01 unicorn master -c ..... 
ec2-user 18406  0.0 12.2 489520 123072 ?       Sl   05:11   0:00 unicorn worker[0] -c .....
ec2-user 18704  0.0  0.0 119436   964 pts/0    S+   05:25   0:00 grep --color=auto unicorn

⑤ 'unicorn master'のプロセスID(左から２番目の番号)をkillする
[ec2-user@ip-111-22-33-444 リポジトリ名]$ kill 18365(上記の場合)
```
```:ターミナル（ローカル）
⑥ サーバー再起動
% bundle exec cap production deploy
```


# 4. エラーとその解決

本番環境にデプロイした時に実際に起こったエラーと解決までの作業を記述します。

## 本番環境で「新規登録」ページに遷移するとエラー

### ①エラーログの確認

```:ターミナル
① logディレクトリに移動
[ec2-user@ip-111-22-33-444 リポジトリ名]$ cd log

② ls でlogディレクトリの中身を確認
[ec2-user@ip-111-22-33-444 log]$ ls
production.log  unicorn.stderr.log  unicorn.stdout.log

③ production.log でログの確認（'tail -f'でログの10行分を表示）
[ec2-user@ip-111-22-33-444 log]$ tail -f production.log

```
<br>
実際にエラーがあった時の表示
![スクリーンショット 2021-05-04 14.05.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1379469/25d0b213-48ce-a3eb-cd49-067d1f24e63d.png)
怪しいのは、一番上のこの部分。

```:ターミナル
[ee4c13d3-......] ActionView::Template::Error (undefind method `map' fo "translation missing: ja.data.order":String):
```
`translation missing: ja.data.orde`ということから、日本語訳がうまくいっていないんじゃないか...?と考えられる。

***
### 【解決】

プロセスを停止(kill)した上で、再起動を行うと反映された。
プロセス停止 → サーバー再起動の手順が上手くいっていなかった...?

***

## 本番環境のディレクトリに日本語翻訳したファイルがない

本番環境のディレクトリに日本語訳するためのファイル（`devise.ja.yml`・`ja.yml`）があるか確認（config / locales の中を確認）。

```:ターミナル
① ls でconfigがあるか確認
[ec2-user@ip-111-22-33-444 リポジトリ名]$ ls
Capfile       README.md  babel.config.js  config.ru  furima.dio  node_modules       public    revisions.log  storage  vendor
Gemfile       Rakefile   bin              current    lib         package.json       releases  shared         test     yarn.lock
Gemfile.lock  app        config           db         log         postcss.config.js  repo      spec           tmp

② configディレクトリに移動
[ec2-user@ip-111-22-33-444 リポジトリ名]$ cd config

③ config内のディレクトリを確認
[ec2-user@ip-111-22-33-444 config]$ ls
application.rb  cable.yml            database.yml  deploy.rb       environments  locales  routes.rb  storage.yml  webpack
boot.rb         credentials.yml.enc  deploy        environment.rb  initializers  puma.rb  spring.rb  unicorn.rb   webpacker.yml

④ localesディレクトリに移動
[ec2-user@ip-111-22-33-444 config]$ cd locales

⑤ localesの中身を確認
[ec2-user@ip-111-22-33-444 locales]$ ls
devise.en.yml  en.yml
```

長々と書きましたが、これは１つずつ確実に中身を確認するために記述したため、本来は以下の記述で`locales`ディレクトリまで移動できます。

```:ターミナル
[ec2-user@ip-111-22-33-444 リポジトリ名]$ cd config/locales
[ec2-user@ip-111-22-33-444 locales]$ ls
devise.en.yml  en.yml
```

`locales`の中みを見ると、日本語訳にするためのファイル（`devise.ja.yml`・`ja.yml`）が見当たらない。
***
###<b>【原因】</b>
コードの変更を、commit → push（もしくはmerge）した時点で満足し、GitHubからEC２へ反映していなかった。

<b><font color="tomato">git push origin master</font></b> のし忘れ。

###<b>【解決】</b>
ターミナルでEC2へ変更を反映。

```:ターミナル
[ec2-user@ip-111-22-33-444 リポジトリ名]$ git pull origin master
```
***

# 5. おわり

本番環境に反映されない時は、以下の確認を行う。

 - 変更・追加をリモートリポジトリにcommit→push（またはmerge）しているか
 - GitHubからEC2へ(git pull origin master)したか
 - EC2インスタンスの再起動
 - エラーログの確認