【Rails】エラーメッセージの表示順を指定する

# はじめに
エラーメッセージを任意の順番に入れ替える方法を調べた内容を記録します。

# 結論
####  バリデーションの記述順の通りに、エラーメッセージが表示される
>バリデーションが失敗すると、バリデーションをトリガーした属性名の下のerrorsコレクションにエラーメッセージを保存します。「Railsガイド」

- 例①（すべて空でcreateアクションを実行した場合）

```rb
validates :login_id, presence: true
validates :email, presence: true
validates :password, presence: true
```

```
ログインIDを入力してください
メールドレスを入力してください
パスワードを入力してください 
```
- 例②
```rb
validates :email, presence: true
validates :password, presence: true
validates :login_id, presence: true
```
```
メールアドレスを入力してください 
パスワードを入力してください
ログインIDを入力してください
```

# 留意点
### Deviseを使う場合

`devise :validatable`を読み込むと、`email`と `password`のバリデーションが実行される
```lib/devise/models/validatable.rb
      def self.included(base)
        base.extend ClassMethods
        assert_validations_api!(base)

        base.class_eval do
          validates_presence_of   :email, if: :email_required?
          validates_uniqueness_of :email, allow_blank: true, case_sensitive: true, if: :devise_will_save_change_to_email?
          validates_format_of     :email, with: email_regexp, allow_blank: true, if: :devise_will_save_change_to_email?

          validates_presence_of     :password, if: :password_required?
          validates_confirmation_of :password, if: :password_required?
          validates_length_of       :password, minimum: proc { password_length.min }, maximum: proc { password_length.max }, allow_blank: true
        end
      end
```
https://github.com/heartcombo/devise/blob/fec67f98f26fcd9a79072e4581b1bd40d0c7fa1d/lib/devise/models/validatable.rb#L28

- 例①
```rb
class User < ApplicationRecord
  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:google_oauth2]

  validates :login_id, presence: true
```
===
```rb
メールドレスを入力してください　# Devise::Models::Validatableのバリデーション
パスワードを入力してください　# Devise::Models::Validatableのバリデーション
ログインIDを入力してください
```
- 例②：「ログインID」のエラーメッセージを最初に表示したい場合は記述順を入れ替える
```rb
class User < ApplicationRecord
  validates :login_id, presence: true
  
  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:google_oauth2]
```
===
```rb
ログインIDを入力してください
メールドレスを入力してください　　# Devise::Models::Validatableのバリデーション
パスワードを入力してください　　# Devise::Models::Validatableのバリデーション
```
### 関連モデルを同時に保存する場合
アソシエーションを定義した箇所の読み込み時に関連モデルのバリデーションが実行される
- 例①
```rb
class User < ApplicationRecord
  validates :login_id, presence: true

  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:google_oauth2]

  has_one :employee
  accepts_nested_attributes_for :employee
```
```rb
class Employee < ApplicationRecord
  belongs_to :user
  validates :name, presence: true
```
===
```rb
ログインIDを入力してください
メールドレスを入力してください
パスワードを入力してください
名前を入力してください　　# Employeeモデルのバリデーション
```
- 例②：関連モデルのエラーメッセージを最初に表示したい場合は記述順を入れ替える
```rb
class User < ApplicationRecord
  has_one :employee
  accepts_nested_attributes_for :employee
  
  validates :login_id, presence: true

  devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable,
         :omniauthable, omniauth_providers: [:google_oauth2]
```
```rb
class Employee < ApplicationRecord
  belongs_to :user
  validates :name, presence: true
```
===
```rb
名前を入力してください  　# Employeeモデルのバリデーション
ログインIDを入力してください
メールドレスを入力してください
パスワードを入力してください
```