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

このように、何かしらの値をデータベースに保存する機能を実装する際はバリデーションの知識が必須になってきます。
バリデーションの基本形
基本的なバリデーションの記述方法は以下のようになります。
ここではユーザーのニックネーム(nickname
)と誕生日(birthday
)の存在チェックを行っています。nickname
とbirthday
が空であれば保存は行われません。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
以下のようにワンライナーで記述することも可能です。
class User < ApplicationRecord
validates :nickname, :birthday, presence: true
end
バリデーションの判別
RailsはActiveRecordオブジェクトを保存する直前にバリデーションを実行し、バリデーションで何らかのエラーが発生するとオブジェクトを保存しません。
その一方でバリデーションを手動で実行することも可能です。
その際に使用するメソッドがvalid?(invalid?)
メソッドです。
valid?
メソッドはバリデーションを実行しエラーがない場合はtrue
を、エラーがある場合にはfalse
を返します。(invalid
メソッドはその反対です。)
class User < ApplicationRecord
validates :nickname, presence: true
end
@user = User.new(nickname: 'タロウ')
@user.valid?
> true
@user = User.new(nickname: nil)
@user.valid?
> false
エラーメッセージの取得
バリデーションが行われた後でerrors
メソッドを使うことで、発生したエラーメッセージを取得することができます。
errors
errors
メソッドはエラーメッセージをハッシュ形式で取得するコマンドです。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors
=>{:nickname=>["can't be blank"], :birthday=>["can't be blank"]}
errors.full_messages
errors.full_messages
メソッドは全てのエラーメッセージを配列で取得するコマンドです。エラーメッセージが複数ある場合で1つずつ表示したい場合は、each
やmap
といった繰り返し処理を使ってエラーメッセージを表示させることになります。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages
=> ["Nickname can't be blank", "Birthday can't be blank"]
errors.full_messages_for(:symbol)
errors.full_messages_for(:symbol)
メソッドは指定した属性のエラーメッセージを配列で取得するコマンドです。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages_for(:email)
=> ["Nickname can't be blank", "Birthday can't be blank"]
エラーメッセージの表示
エラーメッセージを表示するにはエラーの有無を検知し、errors
に格納されているエラーメッセージを取得・表示する必要があります。
例えば、以下のようなコードをビューファイルに記述することで表示が可能になります。
<% if user.errors.any? %>
<div class = "alert">
<ul>
<% user.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
user.errors.any?
でUserモデルに対するエラーの有無を検知します。その後エラーがあればuser.errors.full_messages.each
が実行され、繰り返し処理によって存在するエラーが全て表示されるようになります。
エラーメッセージの日本語化
先ほどの実装でエラーメッセージを表示させることはできましたが、エラーメッセージが英語の表記のままになっています。
ここではエラーメッセージを日本語化する設定を行っていきます。
この設定にはgemである「rails-i18n」を使用します。
gem 'rails-i18n'
% bundle install
デフォルトではロケールが英語(:en
)になっているため、デフォルトの設定を日本語(:ja
)に変更します。ロケールはapplication.rb
で設定することができます。
module HomecareRails
class Application < Rails::Application
# 以下の1行を追加
config.i18n.default_locale = :ja
end
end
続いてconfig/locales
配下にja.yml
を作成し、日本語変換したい文言を設定します。
% touch config/locales/ja.yml
ja:
activerecord:
attributes:
user:
nickname: ニックネーム
birthday: 誕生日
ここまでの設定でエラーメッセージが日本語されているはずです。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages
=> ["ニックネームを入力してください", "誕生日を入力してください"]
エラーメッセージを1つ1つ個別設定すると面倒なので、ja.yml
テンプレートの使用がおすすめです。使いたいエラーメッセージがテンプレートにない場合は自身で追記していく形になります。
エラーメッセージのカスタマイズ
前項ではエラーメッセージを日本語化しましたが「〜を入力してください」のように、「を入力してください」でエラーメッセージが固定されていました。
ここでは、エラーメッセージをカスタマイズする方法について紹介します。
翻訳ファイルであるja.yml
を以下のように編集します。
ja:
activerecord:
attributes:
user:
nickname: ニックネーム
birthday: 誕生日
errors:
models:
user:
blank: が未入力です
これにより「〜を入力してください」の部分が「〜が未入力です」に変換されます。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages
=> ["ニックネームが未入力です", "誕生日が未入力です"]
バリデーションとメッセージの関係は以下のようになっています。
バリデーション | 利用可能なオプション | メッセージ | 式展開 |
---|---|---|---|
confirmation | – | :confirmation | attribute |
acceptance | – | :accepted | – |
presence | – | :blank | – |
absence | – | :present | – |
length | :within, :in | :too_short | count |
length | :within, :in | :too_long | count |
length | :is | :wrong_length | count |
length | :minimum | :too_short | count |
length | :maximum | :too_long | count |
uniqueness | – | :taken | – |
format | – | :invalid | – |
inclusion | – | :inclusion | – |
exclusion | – | :exclusion | – |
associated | – | :invalid | – |
non-optional association | – | :required | – |
numericality | – | :not_a_number | – |
numericality | :greater_than | :greater_than | count |
numericality | :greater_than_or_equal_to | :greater_than_or_equal_to | count |
numericality | :equal_to | :equal_to | count |
numericality | :less_than | :less_than | count |
numericality | :less_than_or_equal_to | :less_than_or_equal_to | count |
numericality | :other_than | :other_than | count |
numericality | :only_integer | :not_an_integer | – |
numericality | :in | :in | count |
numericality | :odd | :odd | – |
numericality | :even | :even | – |
参考: エラーメッセージ内での式展開
しかしこのままの記述だと、blank
のエラーメッセージが全て「〜が未入力です」に変換されてしまいます。特定の属性毎に、例えばUserモデルのnicknameカラムに対してのみエラーメッセージを指定したい場合は以下のようにja.yml
を記載します。
ja:
activerecord:
attributes:
user:
nickname: ニックネーム
birthday: 誕生日
errors:
models:
user:
attributes:
nickname:
blank: は必須入力です
これにより、属性毎にエラーメッセージをカスタマイズすることができます。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages
=> ["ニックネームは必須入力です", "誕生日を入力してください"]
フォーマットのカスタマイズ
これまでのエラーメッセージでは「ニックネームを入力してください」や「誕生日を入力してください」のように「属性名(attribute) + エラーメッセージ(message)」で固定されていました。
ここではフォーマットをカスタマイズする方法について紹介します。
まずはapplication.rb
に以下の1行を追加します。
module HomecareRails
class Application < Rails::Application
config.i18n.default_locale = :ja
# 以下の1行を追加
config.active_model.i18n_customize_full_message = true
end
end
続いてja.yml
を以下のように編集します。
ja:
activerecord:
attributes:
user:
nickname: ニックネーム
birthday: 誕生日
errors:
models:
user:
attributes:
nickname:
format: "%{attribute}: %{message}"
blank: 未入力
これにより、属性毎にフォーマットをカスタマイズすることができます。
class User < ApplicationRecord
validates :nickname, presence: true
validates :birthday, presence: true
end
@user = User.new(nickname: nil, birthday: nil)
@user.valid?
@user.errors.full_messages
=> ["ニックネーム: 未入力", "誕生日を入力してください"]
まとめ
- バリデーションとは、データベースに保存する前に保存内容を検証する機能のこと
- バリデーションを手動で実行するには
valid?
(invalid?
)メソッドが使用できる - エラーの有無を判別するには
any?
メソッドが使用できる - エラーメッセージの日本語化には「rails-i18n」を使用する
- エラーメッセージのカスタマイズは
ja.yml
で行うことができる
参考
今回はRailsにおけるバリデーションのエラーメッセージを取得・表示・日本語化する方法について紹介しました。バリデーションを使いこなせることはRailsエンジニアの基本の1つなので参考になれば幸いです。