今回は、Railsにおけるバリデーションのエラーメッセージを取得・表示・日本語化する方法を解説したいと思います。Railsにおいてバリデーションに関する知識は必須なので、ぜひこの機会に復習しておきましょう。
バリデーションとは
バリデーションとは、データベースに保存する前に保存内容を検証する機能です。
例えば、ユーザー登録の際にニックネームと生年月日が必須項目だと仮定します。しかし、生年月日を入力せずに次に進んでしまいました。すると、エラーメッセージと共に再度入力ページに戻されると思います。これはバリデーションのチェックに引っかかったためです。

このように、データベースに保存する機能(create)を実装する際はバリデーションの知識が必須になってきます。
基本的なバリデーションの記述方法は以下のようになります。モデルに記述するということを覚えておきましょう。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
バリデーションエラーの判別
次にバリデーションのチェックに引っ掛かったかどうか判別するためのコマンドを解説します。これはエラーメッセージを取得・表示する際に必要になります。
バリデーションの判別にはvalid?メソッドを使用します。
@user = User.new
@user.valid?
# バリデーションを通過した場合
> true
# バリデーションに引っかかった場合
> false
エラーの有無を判別するにはany?メソッドを使用します。
@user = User.new
@user.errors.any?
# エラー有り
> true
# エラー無し
> false
エラーメッセージの取得
では実際にエラーメッセージを取得してみます。
よく使うコマンドとしては以下が挙げられるので覚えておきましょう。エラーメッセージはモデルのerrorsに格納されています。
- @user.errors
- @user.errors.full_messages
- @user.errors.full_messages_for(:symbol)
@user.errors
エラーメッセージをハッシュ形式で取得するコマンドです。「rails c」で以下のように確認することができます。
pry(main)> @user = User.new
pry(main)> @user.save
pry(main)> @user.errors
=>{:email=>["can't be blank"], :password=>["can't be blank"], :nickname=>["can't be blank"]}
@user.errors.full_messages
全てのエラーメッセージを配列で取得するコマンドです。エラーメッセージが複数ある場合はeach文を使ってエラーメッセージを表示させましょう。
pry(main)> @user = User.new
pry(main)> @user.save
pry(main)> @user.errors.full_messages
=>["Email can't be blank", "Password can't be blank", "Nickname can't be blank"]
@user.errors.full_messages_for(:symbol)
対象のシンボルのメッセージを配列で取得するコマンドです。具体的には、:symbolの部分にカラム名が入ります。
pry(main)> @user = User.new
pry(main)> @user.save
pry(main)> @user.errors.full_messages_for(:email)
=>["Email can't be blank"]
エラーメッセージの表示方法
続いて、取得したエラーメッセージを表示する方法を紹介します。
まずは、部分テンプレートでエラーメッセージを作成しましょう。部分テンプレートにする理由は、複数ファイルでエラーメッセージを表示することも考慮するためです。
↓ _error_form.html.erb
<% if user.errors.any? %>
<div class = "alert">
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
続いてこのエラーメッセージを呼び出したいファイルで設定しましょう。今回はindex.html.erbで呼び出すと仮定します。
↓ index.html.erb
<%= render 'error_form', locals: { user: @user } %>

エラーメッセージの日本語化
先ほどの実装でエラーメッセージを表示させることができました。しかし、このエラーメッセージは英語の表記のままになっています。
そこで最後は、このエラーメッセージを日本語化する設定を行っていきましょう。この設定にはgemである「rails-i18n」を使用します。
まずはGemfileに「rails-i18n」を記載し、bundle installを実行しましょう。
gem 'rails-i18n'
% bundle install
続いて、デフォルトで日本語のエラーメッセージを使用する設定を行います。
config/application.rbに、以下の一文を追記しましょう。「class ~」の中に記述する点に注意してください。
config.i18n.default_locale = :ja
↓ config/application.rb
require_relative 'boot'
require 'rails/all'
Bundler.require(*Rails.groups)
module アプリケーション名
class Application < Rails::Application
config.load_defaults 5.2
config.i18n.default_locale = :ja
end
end
次に、config/locals以下にja.ymlを作成し、日本語表記したい文言を設定します。日本語変換する記述が網羅されたコードがGithub上に載っているので、そこから丸々コピー&ペーストしましょう。
↓ config/locals/ja.yml
ja:
activerecord:
errors:
messages:
record_invalid: 'バリデーションに失敗しました: %{errors}'
restrict_dependent_destroy:
has_one: "%{record}が存在しているので削除できません"
has_many: "%{record}が存在しているので削除できません"
date:
abbr_day_names:
- 日
- 月
- 火
- 水
- 木
- 金
- 土
abbr_month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
day_names:
- 日曜日
- 月曜日
- 火曜日
- 水曜日
- 木曜日
- 金曜日
- 土曜日
formats:
default: "%Y/%m/%d"
long: "%Y年%m月%d日(%a)"
short: "%m/%d"
month_names:
-
- 1月
- 2月
- 3月
- 4月
- 5月
- 6月
- 7月
- 8月
- 9月
- 10月
- 11月
- 12月
order:
- :year
- :month
- :day
datetime:
distance_in_words:
about_x_hours:
one: 約1時間
other: 約%{count}時間
about_x_months:
one: 約1ヶ月
other: 約%{count}ヶ月
about_x_years:
one: 約1年
other: 約%{count}年
almost_x_years:
one: 1年弱
other: "%{count}年弱"
half_a_minute: 30秒前後
less_than_x_seconds:
one: 1秒以内
other: "%{count}秒未満"
less_than_x_minutes:
one: 1分以内
other: "%{count}分未満"
over_x_years:
one: 1年以上
other: "%{count}年以上"
x_seconds:
one: 1秒
other: "%{count}秒"
x_minutes:
one: 1分
other: "%{count}分"
x_days:
one: 1日
other: "%{count}日"
x_months:
one: 1ヶ月
other: "%{count}ヶ月"
x_years:
one: 1年
other: "%{count}年"
prompts:
second: 秒
minute: 分
hour: 時
day: 日
month: 月
year: 年
errors:
format: "%{attribute}%{message}"
messages:
accepted: を受諾してください
blank: を入力してください
confirmation: と%{attribute}の入力が一致しません
empty: を入力してください
equal_to: は%{count}にしてください
even: は偶数にしてください
exclusion: は予約されています
greater_than: は%{count}より大きい値にしてください
greater_than_or_equal_to: は%{count}以上の値にしてください
inclusion: は一覧にありません
invalid: は不正な値です
less_than: は%{count}より小さい値にしてください
less_than_or_equal_to: は%{count}以下の値にしてください
model_invalid: 'バリデーションに失敗しました: %{errors}'
not_a_number: は数値で入力してください
not_an_integer: は整数で入力してください
odd: は奇数にしてください
other_than: は%{count}以外の値にしてください
present: は入力しないでください
required: を入力してください
taken: はすでに存在します
too_long: は%{count}文字以内で入力してください
too_short: は%{count}文字以上で入力してください
wrong_length: は%{count}文字で入力してください
template:
body: 次の項目を確認してください
header:
one: "%{model}にエラーが発生しました"
other: "%{model}に%{count}個のエラーが発生しました"
helpers:
select:
prompt: 選択してください
submit:
create: 登録する
submit: 保存する
update: 更新する
number:
currency:
format:
delimiter: ","
format: "%n%u"
precision: 0
separator: "."
significant: false
strip_insignificant_zeros: false
unit: 円
format:
delimiter: ","
precision: 3
separator: "."
significant: false
strip_insignificant_zeros: false
human:
decimal_units:
format: "%n %u"
units:
billion: 十億
million: 百万
quadrillion: 千兆
thousand: 千
trillion: 兆
unit: ''
format:
delimiter: ''
precision: 3
significant: true
strip_insignificant_zeros: true
storage_units:
format: "%n%u"
units:
byte: バイト
eb: EB
gb: GB
kb: KB
mb: MB
pb: PB
tb: TB
percentage:
format:
delimiter: ''
format: "%n%"
precision:
format:
delimiter: ''
support:
array:
last_word_connector: "、"
two_words_connector: "、"
words_connector: "、"
time:
am: 午前
formats:
default: "%Y年%m月%d日(%a) %H時%M分%S秒 %z"
long: "%Y/%m/%d %H:%M"
short: "%m/%d %H:%M"
pm: 午後
まとめ
- バリデーションはデータベースに保存する前に保存内容を検証する機能のこと
- バリデーションの判別にはvalid?メソッドを使用する
- エラーの有無を判別するにはany?メソッドを使用する
- エラーメッセージの取得には「@user.errors」、「@user.errors.full_messages」、「@user.errors.full_messages_for(:symbol)」がある
- エラーメッセージの記述は部分テンプレートで分ける
- エラーメッセージの日本語化には「rails-i18n」を使用する
今回は、Railsにおけるバリデーションのエラーメッセージを取得・表示・日本語化する方法を解説しました。ややボリュームが多い内容ですが、1つ1つ理解しながら進めていきましょう。