【Rails】エラーメッセージを日本語化

# 記事概要
Railsでエラーメッセージを日本語にする方法を説明する。

# 言語やフレームワーク
|| 使用技術 |
| ---- | ---- |
| フロントエンド | HTML <br> CSS |
| バックエンド | Ruby 3.2.0 <br> Ruby on Rails 7.0.8.6 |
| データベース | MySQL |
| インフラ | - |
| API | - |
| その他 | - |

# 前提
- モデルにバリデーションが設定されていること

# 手順(コントローラーの処理分岐)
データ保存・更新に成功した場合と失敗した場合に、コントローラーで処理を分岐する
```ruby
class ItemsController < ApplicationController
  # 中略
  def create
    # Itemデータを作成
    @item = Item.new(set_params)
    if @item.save
      # データ保存に成功した場合の処理
      redirect_to root_path
    else
      # データ保存に失敗した場合の処理
      render :new, status: :unprocessable_entity
    end
  end

  # 中略

  def update
    if @item.update(set_params)
      # データ更新に成功した場合の処理
      redirect_to item_path(@item.id)
    else
      # データ更新に失敗した場合の処理
      render :edit, status: :unprocessable_entity
    end
  end

  # 中略
end
```
# 手順(エラー処理を表示)
## エラーメッセージ用ビューファイル
エラーメッセージ用の部分テンプレート(app/views/shared/_error_messages.html.erb)を手動作成し、下記のように記述する
```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 %>
```

エラーメッセージを表示させる部分に、下記を追記する
```erb
# 中略
<%= render 'shared/error_messages', model: f.object %>
# 中略
```

## フラッシュメッセージ
フラッシュメッセージを表示させる部分に、下記を追記する
```erb
# 中略
<%= flash[:notice] %>
<%= flash[:alert] %>
# 中略
```

※この時点でブラウザ画面を確認すると、英語でエラーメッセージが表示される

# 手順(エラー処理を表示)
config/application.rbの言語設定を変更するため、`config.i18n.default_locale = :ja`を追記する
```application.rb
module Pictweet
  class Application < Rails::Application
    # 中略
    config.load_defaults 7.0

    # 日本語の言語設定を追記
    config.i18n.default_locale = :ja
    
    # 中略
    end
end
```

# 手順(Gemの追加)
[rails-i18n](https://github.com/svenfuchs/rails-i18n)を追加するため、Gemfileに`gem 'rails-i18n'`を追記する
```ruby
# 最終行に追加
gem 'rails-i18n'
```
ターミナルで下記コマンドを実行し、Gemを適用する
```
% bundle install
% rails s
```

※この時点でブラウザ画面を確認すると、日本語でエラーメッセージが表示される。ただし、項目名は英語のままである

# 手順(項目名の日本語化)
config/locales/devise.ja.ymlを手動作成する
[devise-i18n](https://github.com/tigrish/devise-i18n/blob/master/rails/locales/ja.yml)のコードを全てコピーし、config/locales/devise.ja.ymlに貼り付ける
※インデントにミスがあるとエラー発生するので、注意

※この時点でブラウザ画面を確認すると、Gem「devise」の項目は日本語になっているが、自身で設定した項目は英語表記のままである

# 手順(項目名の日本語化2)
config/locales/ja.ymlを手動作成する
```ja.yml
ja:
  # モデル項目を日本語に変換
  activerecord:
    attributes:
      # Gem「devise」で作成したUserモデル
      user:
        # Userモデルのnicknameを「ニックネーム」と表示
        nickname: ニックネーム
      item:
        # Itemモデルのnameを「商品名」と表示
        name: 商品名
        
        # ActiveHashを使用している場合、idに対して日本語を設定
        category_id: カテゴリー

        # 'has_one_attached'で紐づけている画像に対して、日本語を設定
        image: 商品画像
        
        # 'belongs_to'で紐づけている外部キーに対して、日本語を設定
        user: ユーザー

  # Formオブジェクトのモデル項目を日本語に変換
  activemodel:
    attributes:
      order_ship:
        post_code: 郵便番号
        prefecture_id: 都道府県
        token: クレジットカード情報
        user: ユーザー
        item: 商品
```

※この時点でブラウザ画面を確認すると、エラーメッセージが全て日本語で表示される

# 手順(モデル単体テストを英語表記に修正)
spec/rails_helper.rbに`I18n.locale = "en"`が記述されている場合、`I18n.locale = "ja"`に修正する

# 手順(モデル単体テストコードを修正)
spec/models/user_spec.rbなどに記載しているエラーメッセージを日本語に変更する

## 修正前
```user_spec.rb
# 中略
context 'ユーザー登録できないとき' do
  it 'emailが空では登録できない' do
    @user.email = ''
    @user.valid?
    expect(@user.errors.full_messages).to include('Email can't be blank')
  end
# 中略
```

## 修正後
```user_spec.rb
# 中略
context 'ユーザー登録できないとき' do
  it 'emailが空では登録できない' do
    @user.email = ''
    @user.valid?
    expect(@user.errors.full_messages).to include('Eメールを入力してください')
  end
# 中略
```

# 備考
- Formオブジェクトの外部キーはアソシエーションを組めないという特性により、項目名を日本語にできない