🛍️

通知機能の実装 part3 (既読機能の実装)

2023/10/08に公開

この記事で分かること

  • 通知機能に既読処理を行う方法
  • 既読済みの通知を削除する方法

前提条件

  • 通知機能(通知を受け取れるようにする)が実装済み

https://zenn.dev/tya0116/articles/f5cf48deee50d9

完成イメージ

テーブル

table_notification

実装手順

  1. 既読・未読機能の追加
  2. 既読済みの通知を削除

実装方法

実装手順に沿って紹介します。

既読・未読機能の追加

(Notifications)テーブルの(checked)カラムを使って真偽判定を行います。

Routeingの設定

ついでに削除機能のルーティングも記述します。

resources :notifications, only: [:index] do
patch :checked, on: :member
delate :destroy_all, on: :collection
end

Controllerの設定

notifications_controller
  def index
    @notifications = current_user.notifications.order(created_at: :desc)
    @unchecked_notifications = @notifications.where(checked: false).order(created_at: :desc)
    @checked_notifications = @notifications.where(checked: true).order(created_at: :desc)
  end

 def checked
  @notification = Notification.find(params[:id])
  @notification.update(checked: true)
  redirect_to notifications_path
 end

checkedカラムがfalseのnotificationsとtrueのnotificationsをそれぞれインスタンスを設定しました。checkedアクションを実行するときは、checkedカラムをtrueにアップデートするように設定しました。

Viewの設定

notifications/index
<div class= "container py-5 px-sm-0">
  <div class= "row">
    <div class="col-10 offset-1">
      <h4>通知一覧<span class= "text-warning"><i class="fa-sharp fa-solid fa-bell"></i></span>
      </h4>
      <% if @notifications.present? %>
      <table class='table'>
      <% @unchecked_notifications.each do |notification| %>
      <tr class= "table_group">
      <%= render notification.action_type, notification: notification %>
      </tr>
      <% end %>
      <% @checked_notifications.each do |notification| %>
      <tr class= "table_group2">
       <%= render notification.action_type, notification: notification %>
      </tr>
      <% end %>
      </table>

    <% else %>
      <div class="text-center">
      通知はありません
    <% end %>
    </div>
  </div>
</div>

【Point】
前半に(@unchecked_notifications)の未読通知を表示し、後半に(@checked_notifications)の既読通知を表示するように設定しました。
また既読か未読かを視覚的にわかるようにtable_groupを設定しました。

application.scss
.table_group {
  background-color: #FFFFEE;
}

.table_group2 {
  background-color: #FFFFEE;
  opacity: 0.6
}

【Point】
既読済みのテーブルは(opacity)を使って透けるように調整し、既読感があるように設定しました。

favorited_to_own_post
 <td>
    <%= image_tag notification.subject.user.get_profile_image(30,30),class: "img_icon" %>
    <%= link_to notification.subject.user.name, user_path(notification.subject.user) %>
    さんがあなたの
    <%= link_to '投稿', item_path(notification.subject.item) %>
    にいいねしました!(<%= notification.subject.created_at.strftime('%Y/%m/%d') %>)
+   <%= link_to checked_notification_path(notification), method: :PATCH do %>
+     <span class= text-success><i class="fa-solid fa-check"></i></span>
+   <% end %>
 </td>

タイプ別のViewで既読済みにできるチェックマークを表示しました。

残りのnotificationタイプにも同様の処理を行います。

今記事のnotificationタイプ
  • commented_to_own_post・・・コメント通知
  • favorited_to_own_post・・・いいね通知
  • followed_me・・・フォロー通知
  • chated_to_own_post・・・DM通知

以上で既読機能は完成です。

通知削除機能を実装

既読済みの通知のみを削除できるように実装します。

Controllerの設定

notifications_controller
  def destroy_all
    notifications = current_user.notifications
    checked_notifications = notifications.where(checked: true)
    checked_notifications.destroy_all
    redirect_to notifications_path
  end

対象を(checked_notifications)の既読済み通知に設定します。

notifications/index
<h4>通知一覧<span class= "text-warning"><i class="fa-sharp fa-solid fa-bell"></i></span>
<% if @checked_notifications.present? %>
 <%= link_to "通知をクリアする", destroy_all_notifications_path, method: :delete,"data-confirm" => "既読済み通知を削除しますか?", class: "ml-2 btn btn-outline-secondary btn-sm"%>
 <% end %>

お好みの場所にボタンを設置して完成です。

感想

今回はcheckedアクションは「✔︎」を押すと実行するように実装したが、テーブル全域のどこでもクリックすると実行に設定したかったです。また非同期にできそうなので、時間があるときに非同期設定をしようと思います。

この記事をかいた人

https://twitter.com/tya_dwc
23/6/1にDWCに入学し、主にRailsの学習に取り組みました。卒業が近づきこれから何で学習をするか悩んだときに、技術ブログをしようと考えました。初心者ですがよろしくお願いします。

Discussion