Ruby Ruby on Rails Web開発 プログラミング

Rails 8.1 + Devise で Noty を使った通知表示


Rails アプリで flash メッセージや Devise のバリデーションエラーを ポップアップ通知(Noty) で表示する方法をまとめます。

この記事を書いてる人

082p
082p

ご訪問、ありがとうございます!

システムエンジニア兼動画クリエーターとして活動しています。
主に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 対応でページ遷移後も通知を確実に表示
082p
082p

これで「通知が出るのに見た目もモダンで統一されている Rails アプリ」の完成です。

-Ruby, Ruby on Rails, Web開発, プログラミング