Rails エラーメッセージの表示方法

## はじめに
RUNTEQに入学して2ヶ月の学習者です。
間違い、改善点等ありましたらコメントいただけると嬉しいです。
## 1.なぜこの記事を作ったのか
エラーメッセージを出そうとしたが、方法が分からなかった。エラーメッセージについての知識が足りていないので備忘録にする。
## 2.環境
- ruby 3.2.2
- Rails 7.1.2
## 3.エラーメッセージについて
<img width= "400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/c26bf78e-179f-e377-2d7b-a6f86850456f.png">

```ruby:user.rb
class User < ApplicationRecord
  validates :name, presence: true
end
```

- 上の画像はNameの値を空にしてユーザーを作成しようとしたもの。
- エラーメッセージは、カラムにバリデーションを設定し、バリデーションの条件を満たさないデータが出来る時に生成される。アプリを使用するユーザーに向けて、何故エラーが出たのかを教えることが出来る。
### どうやってメッセージは生成されるのか
```
rails g scaffold User name:string age:integer
```
アプリケーション作成後、`scaffold`で基盤の作成、先ほどのバリデーションのみ設定してコンソールで確認する。
```ruby: console
irb(main):001> user = User.new(name: "", age: 20)
=> #<User:0x0000000108cbb3b8 id: nil, name: "", age: 20, created_at: nil, updated_at: nil>
irb(main):002> user.errors
=> #<ActiveModel::Errors []>
irb(main):003> user.save
=> false
irb(main):004> user.errors
=> #<ActiveModel::Errors [#<ActiveModel::Error attribute=name, type=blank, options={}>]>
irb(main):005> user.errors.full_messages
=> ["Name can't be blank"]
```
- `irb(main):001>`
ユーザーの作成。`name`の値はバリデーションエラーとなるようにした。
<br>

- `irb(main):002>`
この時点では`errors`メソッド内は空。`errors`メソッドはエラー情報を格納する。
<br>

- `irb(main):003>`
保存してみるが失敗。`save`メソッド内でバリデーションを実行している。
<br>

- `irb(main):004>`
`errors`メソッド内にエラー情報が格納されている。
<br>

- `irb(main):005`
`errors.full_messages`メソッドによりエラーメッセージが配列化されている。
### エラーメッセージの表示方法
rails g scaffoldにて自動生成されたものを見ていきます。
```erb:users/_form.html.erb
<%= form_with(model: user) do |form| %>
  <% if user.errors.any? %>
    <div style="color: red">　
      <h2><%= pluralize(user.errors.count, "error") %> prohibited this user from being saved:</h2>

      <ul>
        <% user.errors.each do |error| %>
          <li><%= error.full_message %></li>
        <% end %>
      </ul>
    </div>
  <% end %>
  
<!-- 以下割愛します -->
```
- `<% if user.errors.any? %>`
`errors`メソッド内に値がある時にエラーメッセージフォームを表示
<br>

- `<%= pluralize(user.errors.count, "error") %>`
エラー件数の表示
`pluralize`ヘルパーは第一引数の数をに合わせて、第二引数の英語を複数形にしてくれる。一応日本語ローマ字でも複数形なっていました。
```erb:
<br>
<%= pluralize(1, "apple") %>
<%= pluralize(2, "apple") %>
<%= pluralize(1, "mouse") %>
<%= pluralize(2, "mouse") %>
<%= pluralize(1, "omoti") %>
<%= pluralize(2, "omoti") %>
```
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/35c8d32e-6e3a-d612-b2df-070fa479885e.png">

- `<% user.errors.each do |error| %>`
`each`メソッドで`errors`メソッドのエラー情報を取り出して、`full_message`で一件づつ表示させる。

### ステータスを設定しないとメッセージが表示されない
```ruby:users_controller.rb
def create
    @user = User.new(user_params)

    respond_to do |format|
      if @user.save
        format.html { redirect_to user_url(@user), notice: "User was successfully created." }
        format.json { render :show, status: :created, location: @user }
      else
        format.html { render :new, status: :unprocessable_entity }
        format.json { render json: @user.errors, status: :unprocessable_entity }
      end
    end
  end
```
`status: :unprocessable_entity`のステータスを設定しないとページが再描画されなくてエラーメッセージが表示されません。`rails g scaffold`では初期設定で記述はあります。
## 4.エラーメッセージの日本語化
このまま設定してもエラーメッセージは英語で表示されてしまいます。なので`rails-i18n`というジェムをインストールして日本語設定をします。
- バージョン rails-i18n (7.0.8)

この記事はエラーメッセージの表示方法の備忘録なので`rails-i18n`と、コードの詳細は端折って記述していきます。

### 手順

```
gem "rails-i18n"
```
Gemfileに記述して`bundle install`
```
rails-i18n (7.0.8)
      i18n (>= 0.7, < 2)
      railties (>= 6.0.0, < 8)
```
Gemfile.lockを見るとインストールされている。サーバーを起動していれば再起動する。
```ruby:config/application.rb
class Application < Rails::Application

    config.i18n.default_locale = :ja
end
```
クラス内へ`config.i18n.default_locale = :ja`を追記。
```config/locales/ja.yml
ja:
  activerecord:
    attributes:
      user:
        name: 名前
```
localesディレクトリ内へja.ymlを作成し上記のコードを記述。
<img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/0a3a38d1-79fa-744c-246d-cdb8c71027bc.png"> <img width="300" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/bfcc685b-7b18-621e-5d27-9358ccfa2382.png">
左が`ja.yml`記述前で右が記述後です。カラムが翻訳されています。
「を入力してください」が翻訳されているのは、rails-i18nのgithubを見ると、localeディレクトリ内にある`ja.yml`から翻訳されていることが分かります。