
Rails アプリで flash メッセージや Devise のバリデーションエラーを ポップアップ通知(Noty) で表示する方法をまとめます。
この記事を書いてる人
ご訪問、ありがとうございます!
システムエンジニア兼動画クリエーターとして活動しています。
主にRubyを得意とし、Ruby on Railsを中心にWebアプリケーション開発を行っています。
業務ではSQLやJavaScriptに触れることも多く、バックエンドからデータベースまで幅広く対応しています。
このブログでは、Ruby on RailsやPython(Django)などのWebアプリケーション開発やデータベース関連の技術記事を中心に、時々C#やWPFなどの開発内容についても発信しています。
Noty の読み込み
CDN 経由で読み込みます。app/views/layouts/application.html.erb の <head> または <body> に追加。
<!-- noty -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.js"
integrity="sha512-lOrm9FgT1LKOJRUXF3tp6QaMorJftUjowOWiDcG5GFZ/q7ukof19V0HKx/GWzXCdt9zYju3/KhBNdCLzK8b90Q=="
crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/noty/3.1.4/noty.min.css"
integrity="sha512-0p3K0H3S6Q4bEWZ/WmC94Tgit2ular2/n0ESdfEX8l172YyQj8re1Wu9s/HT9T/T2osUw5Gx/6pAZNk3UKbESw=="
crossorigin="anonymous" referrerpolicy="no-referrer" />
Flash メッセージを Noty で表示
<p class="notice"> や <p class="alert"> を削除し、以下のように partial をレンダリングします。
<!-- app/views/layouts/application.html.erb -->
<%= render 'shared/notification' %>
shared/_notification.html.erb
<% unless flash.empty? %>
<script>
<% flash.each do |key, value| %>
<% type = key.to_s.gsub('alert', 'error').gsub('notice', 'success') %>
new Noty ({
type: '<%= type %>',
layout: 'topRight',
timeout: '5000',
theme: 'sunset',
text: '<%= value %>'
}).show();
<% end %>
</script>
<% end %>
- alert → error、notice → success に変換
- 表示位置は右上 (topRight)
- タイムアウトは 5 秒
- テーマは sunset
Devise のバリデーションエラーも Noty で表示
app/views/devise/shared/_error_messages.html.erb を以下のように変更。
<% if resource.errors.any? %>
<script>
<% resource.errors.full_messages.each do |message| %>
new Noty ({
type: 'error',
layout: 'topRight',
timeout: '5000',
theme: 'sunset',
text: '<%= message %>'
}).show();
<% end %>
</script>
<% end %>
- サーバーサイドで発生したバリデーションエラーもポップアップで通知されます
- flash と同じテーマ・位置で統一
Turbo 対応(オプション)
Turbo を使用している場合は、ページ遷移で flash が消えてしまうことがあります。その場合、以下のように turbo:load で囲むと安定します。
<script>
document.addEventListener("turbo:load", () => {
<% unless flash.empty? %>
<% flash.each do |key, value| %>
<% type = key.to_s.gsub('alert', 'error').gsub('notice', 'success') %>
new Noty ({
type: '<%= type %>',
layout: 'topRight',
timeout: '5000',
theme: 'sunset',
text: '<%= value %>'
}).show();
<% end %>
<% end %>
});
</script>
まとめ
- Flash メッセージも Devise エラーも Noty で統一して表示
- 見た目がモダンでユーザー体験が向上
- Turbo 対応でページ遷移後も通知を確実に表示
これで「通知が出るのに見た目もモダンで統一されている Rails アプリ」の完成です。


