こんにちは!まろんぼーいです。
今回の記事は、フラッシュメッセージ、エラーメッセージのファイル作成、適用方法についてのメモです。
このブログでは、過去に完全初心者の僕が作ったWebアプリを参考に、
初心者なりに試行錯誤しながらその改良版を作っていく過程をお見せしています。
このシリーズを追っていくだけで、初心者なりのRailsを使ったWebアプリの作り方が見ていただけると思います。
同じ初心者の方の参考になればうれしいです!
〇フラッシュメッセージ、エラーメッセージとは?
始めに、フラッシュメッセージ、エラーメッセージがどのようなものか説明します。
まず前提として、エラーメッセージ、フラッシュメッセージともに、アプリに表示されているHTMLとは少し異なり、ポップアップしてくるのが特徴です。
特定の条件(「ルールを満たさないエラーが発生した」、「ログイン、登録等特定の動作が完了した」など)が満たされた場合、
アプリの上部などにポンっと現れるメッセージとなっています。
それぞれの説明を書いておくと、
フラッシュメッセージは、特定の動作が完了した際、または完了できなかった場合に現れるメッセージです。
多いのは、「ログインに成功しました」、「投稿しました」、「ログインに失敗しました」、「投稿に失敗しました」などです。
このような動作が成功(失敗)し、トップページなどに遷移した際にポップアップされます。
エラーメッセージはその名の通り、エラーが発生した際にポップアップされるメッセージです。
具体的には、設定されているルール(バリデーション)を満たさなかった場合に、何が満たさなかったかの理由がポップアップされます。
例えばユーザ新規登録画面で、パスワードを6文字以上とするバリデーションを適用していた場合に5文字以下のパスワードすると、エラーメッセージが現れます。
フラッシュメッセージは、特定の動作が完了した際に現れるメッセージです。
多いのは、「ログインに成功しました」、「投稿しました」などです。
このような動作が成功し、トップページなどに遷移した際にポップアップされます。
それではそれぞれのコードの書き方を説明していきます。
〇フラッシュメッセージ
まずフラッシュメッセージ適用の流れを説明すると、
①フラッシュメッセージのパーシャルファイル作成
②表示させたい場所のcontrollerにflashの記述
③application.html.erbでrender
となります。
順を追って説明します。
①フラッシュメッセージのパーシャルファイル作成
フラッシュメッセージのファイル名は、_flash_messages.html.erbとすることが通例となっているようです。
頭に「_」を入れることを忘れないように注意。
(特定のページに適用させるパーシャルファイルのため)
格納場所は、viewフォルダのlayoutsの中に入れます。
コードは以下のようにしています。
1 2 3 |
<% flash.each do |message_type, message| %> <div class="alert alert-<%= message_type %>"><%= message %></div> <% end %> |
簡単にイメージを言うと、
1行目と3行目:該当するflashに対して以下(2行目)の操作を行う
2行目 :メッセージ(<%= message %>)を表示する(表示色はmessage_typeに従う)
2行目でclassをalertとalert-<%= message_type %>としています。
これはbootstrapの機能で、「alert-タイプ」というクラスを指定すると、そのタイプの表示色になります。
例えば「alert-success」は緑、「alert-danger」は赤です。
ここで疑問になるのが、
「このメッセージを表示するとあるけど、メッセージはどこで定義されている?」かと思います。
②表示させたい場所のcontrollerにflashの記述
そこで参照するのが、controller。
例えば僕のアプリのusers_controller.rbのcreateメソッド、
つまりユーザ新規登録画面で各項目の入力を終え、「登録ボタン」を押した際の動作に関するcontrollerを見てみます。
1 2 3 4 5 6 7 8 9 10 11 |
def create @user = User.new(user_params) if @user.save flash[:success] = 'ユーザを登録しました。' redirect_to @user else flash.now[:danger] = 'ユーザの登録に失敗しました。' render :new end end |
注目は、3行目以降。
「if @user.save」は、英語を直訳すると、「もし@userがセーブできたら」、
つまり、ユーザ新規登録が正常に完了した場合です。
この場合の動作が、 「flash[:success] = ‘ユーザを登録しました。’ 」と「redirect_to @user」となります。
この「flash[:success] = ‘ユーザを登録しました。’ 」に注目!
このsuccessが、今回のフラッシュメッセージのmessage_typeとなります。
そして肝心のメッセージが、「ユーザを登録しました。」となるわけですね。
同様に、下に進んでいくと、
else、これは英語で「その他」を示すので、
ユーザ登録が正常にできなかった場合です。
この場合は、danger(赤色)タイプで、「ユーザの登録に失敗しました。」というフラッシュメッセージが出るようになります。
このように、フラッシュメッセージを適用させたい場所のcontrollerにflashに関する記述をすることでフラッシュメッセージが適用できますが、
まだやることがあります!
それは、先ほど作成したパーシャルファイルをapplication.html.erbでrender(適用)させることです。
③application.html.erbでrender
application.html.erbは_flash_messages.html.erbと同じくlayoutsのフォルダ内に格納されています。
このファイルは、アプリ全体に適用させるファイルとなるので、
ここれrenderしておけばすべてのviewページでフラッシュメッセージを適用することができます。
renderの仕方は簡単で、
ファイル内の<body>と</body>で囲まれた部分の間に以下の一文を入れるだけです。
1 |
<%= render 'layouts/flash_messages' %> |
これで適用完了となります!!
〇エラーメッセージ
エラーメッセージについては、以下の流れで進めていきます。
①フラッシュメッセージのパーシャルファイル作成
②適用させたいページでrender
①フラッシュメッセージのパーシャルファイル作成
エラーメッセージのファイル名は、_error_messages.html.erbとすることが通例となっているようです。
格納場所は、フラッシュメッセージと同様にviewフォルダのlayoutsの中に入れます。
エラーメッセージのコードは以下のようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 |
<% if model.errors.any? %> <div id="error_explanation" class="alert alert-warning"> <ul class="mb-0"> <% model.errors.full_messages.each do |message| %> <li> <%= message %> </li> <% end %> </ul> </div> <% end %> |
1行目で、「エラーがあれば」という条件文を設定しています。
(エラーがなかったら必要がないので。)
3行目以降では、該当するエラーをリストにして表示するコードを書いています。
エラーメッセージは複数ある場合があるため、リスト化しているんですね。
(コードの中身は詳しく覚える必要なしです!(笑))
ちなみにclassはalert-warningとしており、表示色は黄色となります。
②適用させたいページでrender
フラッシュメッセージではcontrollerの操作を行いましたが、
エラーメッセージの場合はバリデーションエラーに対応したメッセージがデフォルトで設定されています。
なので、controllerの操作は必要ありません。
次に必要なのが、表示させたいページにrenderすることです。
フラッシュメッセージと違い、エラーメッセージを表示するのは、
ユーザが入力するフォームがあるページのみです。
例えばユーザ新規登録ページや、投稿ページが当てはまります。
適用させたいページに、以下の文を追加します。
1 |
<%= render 'layouts/error_messages', model: f.object %> |
こちらですが、注意点があります。それは、renderする場所です。
ユーザ登録画面のように、複数のフォームを入力する場合は、すべてのフォームにrenderできるよう配置する必要があります。
例えば僕が作った以下のユーザ新規登録用のviewファイルでは、以下のようにrenderします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
<div class="row"> <div class="col-sm-6 offset-sm-3"> <%= form_with(model: @user, local: true) do |f| %> <%= render 'layouts/error_messages', model: f.object %> <!-- render文 --> <div class="form-group"> <%= f.label :name, 'ユーザ名' %> <%= f.text_field :name, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :email, 'Email' %> <%= f.email_field :email, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password, 'パスワード' %> <%= f.password_field :password, class: 'form-control' %> </div> <div class="form-group"> <%= f.label :password_confirmation, 'パスワード確認' %> <%= f.password_field :password_confirmation, class: 'form-control' %> </div> <%= f.submit '登録', class: 'btn btn-primary btn-block' %> <% end %> </div> </div> |
上のコードでは、form_with文を用いてユーザ情報の項目を複数設けています。
form_with文についてわからない場合は以下の記事をご覧ください。
このコードでは、それぞれの項目が<div>で囲まれています。
その項目全体をform_withで囲っているという構造となっています。
ここで、それぞれの項目の<div>の中でrenderしてしまうとその項目にしか適用されないため、
項目の<div>からは外し、かつform_with文の中に入れるように記述する必要があるんですね。
まあとにもかくにも、これで適用完了となります!!
適用したエラーメッセージ、フラッシュメッセージは、以下のようにポップアップされます。
(ただし僕のアプリではエラーメッセージを日本語に変更しています。デフォルトは英語なので、エラーメッセージは英語で表示されるかと思います。)

赤い部分がフラッシュメッセージ、黄色の部分がエラーメッセージです。
補足の記事にしては長い記事になってしまいましたが、
ご覧いただきありがとうございました!!!