Railsのエラーメッセージの日本語化【devise/Formオブジェクト等】

# 背景
未経験からエンジニアになるために勉強中です。

簡単なアプリケーションを作成している際に、バリデーションエラーのメッセージが英語なことに引っ掛かり、
エラーメッセージを日本語化する方法を調べていたところ、
知りたい情報が1つにまとまっている記事が見つからなかったため、
自分の備忘録かつ、同じようにプログラミングを勉強中でお困りの方の役に立てばと思い記事を作成しました。
まだ至らぬ点があるとは思いますが、何かお気づきの点があればコメントにてご指摘ください。

# 環境
* ruby 2.6.5
* Rails 6.0

# 変更前の画面（一例）
何も設定をしていないと、バリデーションエラーのメッセージは以下の画像のように英語で出力されます。
![スクリーンショット 2020-10-28 13.30.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/0913ddbc-13a8-2223-6b9a-959cf1526e8e.png)

# 変更後の画面（一例）
変更後は以下の画像のように日本語でエラーメッセージが出力されます。
![スクリーンショット 2020-10-28 13.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/fcb7b84f-6c5a-9c93-e875-44fb5b456af5.png)


# 日本語化の準備
## ・下準備①（Gemのインストール）
エラーメッセージを日本語化するためには、rails-i18nというgemを使用します。
Gemfileに以下の一文を追加して、ターミナルにてbundle installを実行してください。

```ruby
gem 'rails-i18n'
# Gemfileに上記コードを記載
```

## ・下準備②（localeの言語設定変更）
次にconfig/application.rbに以下の一文を追記し、言語設定を変更します。
追記後に、サーバ再起動すると下記画像のようにエラーメッセージの一部が日本語化されます。

```ruby:config/application.rb
class Application < Rails::Application
    config.load_defaults 6.0
    # この下に下記のコードを記載
    config.i18n.default_locale = :ja
    # 上記のコードを記載
  end
```

![スクリーンショット 2020-10-28 13.55.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/9d6aff1a-9982-1b25-d50f-07c2cd5978be.png)

しかし、このままではmodelの属性名は英語のままです。
ですので、次はそこを日本語に変更します。


## ・カラム名を日本語に変更する
modelの属性名を変更するためには、日本語での対応表を作る必要があります。
config/locales/models/に、ja.ymlというファイルを作成して、以下のようにカラム名とそれに対応する日本語を記述してください。

```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    models:
      item: 商品
    attributes:
      item:
        image: 商品の画像
        name: 商品名
        details: 商品の説明
        price: 価格
```

私はitemというモデルの属性名を変更したかったので、コード内にitemと記載しております。**自身の変更したいモデルに合わせて、上記コードのitemという所を変更**してください。

## ・上記の対応表を読み込む
上記で設定したファイルは自動では読み込まれません。
なので、config/application.rbにこのymlファイルの読み込む一文を追記します。

```ruby:config/application.rb
class Application < Rails::Application
    config.load_defaults 6.0
    config.i18n.default_locale = :ja
# この下に下記のコードを記載
config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.yml').to_s]
# 上記のコードを記載
  end
```

ここまで設定ができていれば、下記のように全て日本語表記に変わっているはずです。

![スクリーンショット 2020-10-28 13.33.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/7d35209d-beb3-513e-3f6d-d68c95f6d30f.png)

## ・わかりやすいエラーメッセージへ変更
rails-i18nというGemを使用すれば大体のエラーメッセージを日本語に変換してくれますが、
自分でバリデーションを設定した際などに下記のように、
一見しただけではわからないような出力をされる場合があります。
そのような場合は自身でエラーメッセージを設定してあげましょう。
以下は一例になります。
### 【例】
ActiveHashを用いて都道府県名をプルダウン形式で選択できるようにし、それに対して自身でバリデーションをかけた場合
![スクリーンショット 2020-10-28 15.14.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/0bb18651-a1bf-89a4-2c97-66513964d661.png)

### «変更前»
![スクリーンショット 2020-10-28 15.09.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/be708e4f-569b-8275-454d-92a6ff7e76fb.png)

```ruby:バリデーションをかけたモデル内のコード
   # 省略
with_options presence: true do
   # 省略
    validates :prefecture_id, numericality: { other_than: 1 }
   # 省略
  end
```

### «変更後»
![スクリーンショット 2020-10-28 15.14.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/6c7fdd98-5738-d2ca-c19a-cfdf78d20714.png)


```ruby:バリデーションをかけたモデル内のコード
   # 省略
with_options presence: true do
   # 省略
    validates :prefecture_id, numericality: { other_than: 1 ,message: 'を選択してください'}
   # 省略
  end
```
上記のように**message: 'メッセージ内容'**という風にオプションを設定してあげるとよりわかりやすい日本語に変更できます。

## ・さらにカラム名を追加したい場合
カラム名をさらに追加したい場合は、下記のように自身で追加してください。

```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    models:
      item: 商品
    attributes:
      item:
        image: 商品の画像
        name: 商品名
        details: 商品の説明
        price: 価格
        # ここから下に下記のように自身でカラム名と日本語の対応表を記載
        category_id: カテゴリー
        status_id: 商品の状態
        prefecture_id: 発送元の地域

```

# 独自に定義したFormオブジェクトの日本語化する場合
## ・下準備
上記までの設定ができていれば特に必要ありません。
できていなければ、上記手順に従って下準備(Gemのインストール等)と対応表(ja.yml)の作成、
対応表の読み込み(config/application.rbに追記)まで行いましょう。

## ・config/locales/models/ja.ymlを編集
config/locales/models/ja.ymlを下記のように追記します。

```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    models:
      item: 商品
    attributes:
      item:
        image: 商品の画像
        name: 商品名
        price: 価格
        details: 商品の説明
# ここから下に下記のコードを追記
  activemodel:
    attributes:
      user_purchase:
        city: 市区町村
        postal_code: 郵便番号
        phone_number: 電話番号
        prefecture_id: 都道府県
        house_number: 番地
        building: 建物名
# 上記のコードを追記（カラム名等は自身で変更してください）
```
自身で定義したFormオブジェクトを日本語化するには、**activemodel:**と記載しその下に設定してください。
きちんと設定をしないと日本語に変更をされません。

## 補足
ActiveModel::Modelと設定しているため、activerecord:下のattributes:にコードを記載しても反応しません。

```ruby:Formオブジェクトを設定したモデル内のコード
class UserPurchase
  include ActiveModel::Model # 自身でActiveModel::Modelを設定している
  # 省略
end
```


```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    models:
      item: 商品
    attributes:
      item:
        image: 商品の画像
        name: 商品名
        price: 価格
        details: 商品の説明
# 設定がActiveRecordではないので、ここから下にコードを書いても反応しません
```

# deviseの日本語化
簡単にユーザー登録機能等が実装できるdeviseもデフォルトの設定は英語です。
こちらも日本語に変更できます。

## 変更前の画面（一例）
![スクリーンショット 2020-10-28 16.08.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/c4183890-bfaa-579a-842f-dbb5c7e5196f.png)


## 変更後の画面（一例）
![スクリーンショット 2020-10-28 16.08.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753344/f2f26004-43ef-8ba3-01ca-f6a3a3307720.png)


## ・Gemのインストール
deviseのエラーメッセージを日本語化するためには、devise-i18nとdevise-i18n-viewsというgemを使用します。
Gemfileに以下の一文を追加して、ターミナルにてbundle installを実行してください。

```ruby
gem 'devise-i18n'
gem 'devise-i18n-views'
# Gemfileに上記コードを記載
```

## ・日本語対応表の作成
コマンドにて日本語翻訳ファイルを生成します。
ターミナルにて下記のコマンドを実行してください。

```ruby
rails g devise:views:locale ja
# 下記のように実行結果が表示されれば成功です。
  create  config/locales/devise.views.ja.yml
```

きちんとファイルが生成されているか確認しましょう。

```ruby:config/locales/devise.views.ja.yml
ja:
  activerecord:
    errors:
      models:
        user:
          attributes:
            email:
              taken: "は既に使用されています。"
              # 以下長すぎるため省略
    unlocks:
      new:
        resend_unlock_instructions: "アカウントの凍結解除方法を再送する"
              # 上記が最後の行です
```

## ・localeの言語設定変更
すでに設定をしてある場合はこの作業は不要です。
してない場合は下記のコードを追記しましょう

```ruby:config/application.rb
class Application < Rails::Application
    config.load_defaults 6.0
    # この下に下記のコードを記載
    config.i18n.default_locale = :ja
    # 上記のコードを記載
  end
```

ここまで作業が完了したら、サーバーを再起動したら日本語に変更されているはずです。

## ・さらにカラム名を追加したい場合
カラム名をさらに追加したい場合は、下記のように自身で追加してください。

```ruby:config/locales/models/ja.yml
ja:
  activerecord:
    errors:
      # 以下長いので省略
              confirmation: "が内容とあっていません。"
    attributes:
      user:
        current_password: "現在のパスワード"
        name: "名前"
        email: "メールアドレス"
        password: "パスワード"
        password_confirmation: "確認用パスワード"
        remember_me: "次回から自動的にログイン"
     # 下記に必要があれば自分でカラム名とそれに対応する日本語を追加
        nickname: "ニックネーム"
        first_name: "名前"
        last_name: "名字"
        birthday: "生年月日"
     # 上記のように記載
    models:
       user: "ユーザ"
     # 以下長いので省略
```

# まとめ
以上が私が行ったエラーメッセージの日本語化でした。
必要があれば、修正・追記をしていきます。
ここまでご覧いただき誠にありがとうございました。
何かお気づきの点などございましたら、コメントにてご連絡ください。

# 参考文献
[Railsのバリデーションエラーのメッセージの日本語化](https://qiita.com/Ushinji/items/242bfba84df7a5a67d5b "Railsのバリデーションエラーのメッセージの日本語化")
[RailsのFormオブジェクトの日本語化](https://qiita.com/jacoyutorius/items/e0d2cfdb61ff4c4fd1e7 "RailsのFormオブジェクトの日本語化")
[ActiveRecordのvalidatesで表示されるエラーメッセージのフォーマットを変更する](https://qiita.com/okeicalm/items/9638250ddfb361d80a16 "ActiveRecordのvalidatesで表示されるエラーメッセージのフォーマットを変更する")
[【Rails5】Devise-i18nで日本語化する](https://remonote.jp/rails-devise-i18n-locale-ja "【Rails5】Devise-i18nで日本語化する")
上記の記事を参考にさせていただきました。こちらの記事の方が詳しく書いていることもありますので、
そちらも是非参考にしてみてください。