errorメッセージを個別で出したい
色々と調べながらやってるうちに知らない間にerrorメッセージを出せるようになってしまったが、やったことに自分の頭がついていっていないので、落ち着いてまとめてみる。
エラーメッセージ用のテンプレートの作成
まずはじめに全てのエラーメッセージを配列で取得します。が、エラーメッセージ用の部分テンプレートを作成するのが先です。いろいろなところで使うので、viewに書き込むと直すのが手間になってしまいます。views/shared/_error_messages.html.erb
としておきましょう。
<% if model.errors.any? %> <div class="alert alert-warning"> <ul> <% model.errors.full_messages.each do |message| %> <li><%= message %></li> <% end %> </ul> </div> <% end %>
さて、上のように書くことで、エラーメッセージを配列で取得でき、複数のエラーメッセージがある可能性がある(自分で作っていれば)ので、eachを使って、全て取得します。一行ずつ丁寧にみていきます。
- エラーメッセージ用のテンプレートの作成
- 1行目 <% if model.errors.any? %>
- 4行目 <% model.errors.full_messages.each do |message| %>
- 参考
1行目 <% if model.errors.any? %>
<% if model.errors.any? %>
errors.any?
はエラーがあるかどうかの真偽を出してくれるメソッドです。じゃあ、model
は?というと、呼び出す先で指定しているものになります。呼び出し先をviews/users/new.html.erbとでもしましょう。
<%= form_with model: @user, local: true do |f| %> <%= render 'shared/error_messages', model: f.object %> ...
<%= render 'shared/error_messages', model: f.object %>
の部分で呼び出しをしていて、model: f.object
のmodel
の部分が、<% if model.errors.any? %>
のmodelと対応しています。では、f.object
ってなんだろう?ということで調べていきます。
model: f.objectとは
f
はフォームビルダー変数といい、
<%= form_with model: @user, local: true do |f| %>
form_with
で生成された|f|
の部分です。このフォームビルダー変数には様々なメソッドがあり、text_field
(一行のテキスト投稿フォーム)やselect
(選択肢を作成)など様々ある。f.object
には、入力したデータが入っています。つまり、model: @user
の情報をもっていることになるので、userコントローラーのnewアクションとつながっていることになる。かなり遠いところまで行くけど、そういうことみたい。
4行目 <% model.errors.full_messages.each do |message| %>
まず、はじめのmodel
には、呼び出し先の
<%= form_with model: @user, local: true do |f| %>
の@userが代入されます。そして、errorsメソッドで@userの持っているエラーを表示してくれ、full_messages
でエラーの文章のみを配列で表示してくれます。そして、each do |message|
でエラーの配列を一つ一つ処理してくれる、というようになっているようです。
これでエラーメッセージが個別で出る動きが分かった。難しい。
参考
https://yama2-0506.hatenablog.com/entry/2020/12/11/083007 https://qiita.com/ryuuuuuuuuuu/items/1a1e53d062bff774d88a