実装内容
下記のように未読メッセージがあった場合にバッジを表示させる
実装の目的
新規でメッセージを受信した際にアテンションがなく、未読メッセージの存在が見える化できていなかった
そのため、ハンバーガーメニューの送受信メッセージ一覧に未読メッセージ数のバッジを表示できるように実装をおこなった。
手順
1. chat_rooms_controllerのshowアクションでページが開いた際に下記のコード相手のidをview側に渡す。
user_chat_rooms_controller.rb
# メッセージの受信者のidをUserChatRoomから自分以外で検索し代入。未読アテンション表示のための準備として
@receive_user = UserChatRoom.where(chat_room_id: params[:id]).where('user_id != ?', current_user.id).first
この手順は次の説明するshowページ内でメッセージを相手に送信する際に必要となるため。
2. chat_rooms_controllerのshowページでメッセージを送信する際に上記1で渡した@receive_user.user_idをhidden_fieldでuser_messages_pathに一緒に送る。
views/chat_rooms/show.haml
.message-container__input
.message-container__input__message
= form_with model: @message, url: user_messages_path(user_id: current_user.id), local: true do |f|
= f.text_area :content, placeholder: "メッセージを入力して下さい" , class: "message-container__input__message__area", autocomplete: "off"
= f.hidden_field :chat_room_id, value: @chat_room.id
-# メッセージの受信者のidをUserChatRoomから自分以外で検索し代入。未読アテンション表示のための準備として
= f.hidden_field :receive_user_id, value: @receive_user.user_id
= f.submit "送信",class:"post-btn"
3. ストロングパラメーターに :receive_user_idを追加
controllers/messages_controller.rb
def create
@message = Message.new(message_params)
~中略~
def message_params
params.require(:message).permit(:content, :chat_room_id, :receive_user_id).merge(user_id: current_user.id)
end
4. 既読処理メソッド
- 該当のチャットルーム内で自分宛てのメッセージがあるかチェック
- 自分宛てのメッセージがあれば、そのレコードを取得する
- 既読の情報となるカラム(カラム名: receive_user_id_checked_message)も持たせてupdateで更新する。
controllers/chat_rooms_controller.rb
def show
if Message.where(chat_room_id: params[:id]).where(receive_user_id: current_user.id).present?
@room_message = Message.where(chat_room_id: params[:id]).where(receive_user_id: current_user.id)
@room_message.update(receive_user_id_checked_message: current_user.id)
end
5. 自分宛のメッセージがあり、未読の物をカウントして表示させるためのヘルパーメソッド
- 自分宛のメッセージ件数を取得
- 自分宛のメッセージで既に既読となった件数を取得
- その2つの差分が未読メッセージ数となる
- 未読メッセージがあった際にビューページに表示させたいHTML要素を持たせてビューに飛ばすことができるようにcontent_tagを使用した。(未読メッセージなければHTML空)
app/helpers/application_helper.rb
# 未読メッセージ表示のメソッド
def new_message_badge
receive_user = Message.where(receive_user_id: current_user.id).count
receive_user_checked_message = Message.where(receive_user_id_checked_message: current_user.id).count
message_count = receive_user - receive_user_checked_message
if 0 == message_count
else
# 未読メッセージがある際にdiv要素を吐き出させてハンバーガーメニュー内に配置する。
# 未読メッセージが無い際に未読バッジを表示させないため
content_tag(:div, message_count, class: 'new-message-badge')
end
end
6.ビュー側の処理
下記の記述で上項で作成した未読バッジ表示のためのメソッドを呼び出す。
(表示させたい任意の位置に置く)
views/hoge.html.haml
%p= new_message_badge
以上