未読通知カウント アイコンバッチ

# はじめに
ポートフォリオ制作やっと一旦製作終えました！
今回は通知の未読カウントとDMの未読カウントを実装しました！
未読がある場合はアイコンバッチがつくようにしています
アウトプットとしてまとめます

※旅行やデートのプランを共有するアプリなので、
投稿機能はPostではなくPlanを使用しています！

通知機能の実装方法については、下記に記載しています

https://qiita.com/3rarara/items/1e18838a9fdb22dd535a

# 完成物

![スクリーンショット 2024-06-27 22.20.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782860/1580f956-5cae-42f6-eb72-8bf79ad90d2b.png)

# コントローラー
どの画面でもバッチをつけるために、application_controller.rbに記述します

```application_controller.rb
class ApplicationController < ActionController::Base
  before_action :set_unread_notifications_count
  before_action :set_unread_chats_count

  private

  def set_unread_notifications_count
    @unread_notifications_count = user_signed_in? ? current_user.notifications.where(read: false).count : 0
  end

  def set_unread_chats_count
    if user_signed_in?
      # current_userが参加している全てのルームを取得
      room_ids = current_user.user_rooms.pluck(:room_id)
      # ルーム内でcurrent_userが送信者ではない、未読のチャットをカウント
      @unread_chats_count = Chat.where(room_id: room_ids, read: false).where.not(user_id: current_user.id).count
    else
      @unread_chats_count = 0
    end
  end

end
```

```application_controller.rb
  def set_unread_notifications_count
    @unread_notifications_count = user_signed_in? ? current_user.notifications.where(read: false).count : 0
  end
```

ユーザーがログインしている場合に、current_userの未読通知数を取得
ログインしていない時は0にする

```application_controller.rb
  def set_unread_chats_count
    if user_signed_in?
      # current_userが参加している全てのルームを取得
      room_ids = current_user.user_rooms.pluck(:room_id)
      # ルーム内でcurrent_userが送信者ではない、未読のチャットをカウント
      @unread_chats_count = Chat.where(room_id: room_ids, read: false).where.not(user_id: current_user.id).count
    else
      @unread_chats_count = 0
    end
  end
```

チャット機能の実装方法は様々な方法があるため、実装方法によって変更してください
今回はuser_roomからroom_idを取得して、未読がどのルームで発生しているかを取得しています

チャットルーム一覧にも未読バッチをつけるためchats_controller.rbにも記述します

```chats_controller.rb
class Public::ChatsController < ApplicationController
  # チャットルーム一覧
  def index
    @user_rooms = current_user.rooms.includes(:users).map do |room|
      other_user = room.users.where.not(id: current_user.id).first
      unread_chats_count = Chat.where(room_id: room.id, read: false).where.not(user_id: current_user.id).count
      { room: room, other_user: other_user, unread_chats_count: unread_chats_count }
    end
  end
end
```

# ビュー
#### フッター

```_footer.html.erb
  <li class="nav-item mx-3" style="position: relative;">
    <%= link_to notifications_path, class: "menu-icon" do %>
      <i class="fa-solid fa-bell fa-xl" style="color: #FFD43B;"></i>
      <p class="text-center mt-3" style="color: #FFD43B; font-size: 10px;">通知</p>
      <% if @unread_notifications_count.to_i > 0 %>
        <span class="badge" style="position: absolute; top: -20px; right: -8px; background-color: red; color: #FFD43B; border-radius: 50%; padding: 2px 5px; font-size: 12px;">
          <%= @unread_notifications_count %>
        </span>
      <% end %>
    <% end %>
  </li>

  <li class="nav-item mx-3" style="position: relative;">
    <%= link_to chats_path, class: "menu-icon" do %>
    <i class="fa-solid fa-envelope fa-xl" style="color: #FFD43B;"></i>
    <p class="text-center mt-3" style="color: #FFD43B; font-size: 10px;">DM</p>
      <% if @unread_chats_count.to_i > 0 %>
        <span class="badge" style="position: absolute; top: -20px; right: -8px; background-color: red; color: #FFD43B; border-radius: 50%; padding: 2px 5px; font-size: 12px;">
          <%= @unread_chats_count %>
        </span>
      <% end %>
    <% end %>
  </li>
```

親要素である`<li>`に`position: relative`を付与することで、
未読バッチの場所を通知ボタンから設定することができます
`position: absolute; top: -20px; right: -8px;`で位置を調整
カラーやボタンのレイアウトなどはカスタマイズしてください！

#### チャットルーム一覧

```index.html.erb
<% if @user_rooms.present? %>
  <% @user_rooms.each do |user_room| %>
    <% room = user_room[:room] %>
    <% other_user = user_room[:other_user] %>
    <% unread_chats_count = user_room[:unread_chats_count] %>
    <div class="row mb-3 bg-light p-3 rounded" style="position: relative;">
      <% if unread_chats_count > 0 %>
        <span class="badge" style="position: absolute; top: -8px; right: -8px; background-color: red; color: #FFD43B; border-radius: 50%; padding: 5px 10px; font-size: 20px;">
          <%= unread_chats_count %>
        </span>
      <% end %>
      <%= link_to user_path(other_user) do %>
        <%= image_tag other_user.get_profile_image(90, 90), class: "rounded-circle mx-auto d-block" %>
      <% end %>
      <%= link_to other_user.name, chat_path(other_user), class: 'text-decoration-none' %>
  <% end %>
<% else %>
  チャットルームがありません
<% end %>
```

# さいごに
ざっくりとですがこんな感じです
誤り等ありましたら教えていただけますと幸いです！

# 参照資料
参考にさせていただきました！
ありがとうございました！

https://qiita.com/you8/items/c6a8550165f05480d9b0

https://qiita.com/you8/items/2703458bb4248e2a8eec