😊

DM通知機能実装

に公開

はじめに

DMにも通知機能をつけてみようと思って付けてみました。

コントローラ

app/controllers/public/messages_controller.rb




# 新規作成された@messageに紐づくroomを@roomに格納する
   @room = @message.room
# 本引数を2つ持たせてcreate_notification_dmメソッドを実行
 @room.create_notification_dm(current_user, @message.id)




meaasageとroomは1対多の関係なのでアソシエーションの関係を使うと
上記に使い方ができるよ!!

create_notification_dmは
これからRoomモデルに定義する
create_notification_dmメソッドを呼び出しており
実行後、roomモデルに動作が移るよ!

(current_user, @message.id)は
Notificationモデルに
・現ユーザーのidを保存
・メッセージを保存
するために、メソッドに渡す本引数として設定。

追加したカラム

model.rb
t.integer :room_id
t.integer :message_id

追加したモデル

モデルは一覧を載せていきます。

app/models/message.rb

class Message < ApplicationRecord
  has_many :notifications, dependent: :destroy
  belongs_to :user
  belongs_to :room
end


app/models/message.rb

class Message < ApplicationRecord
  has_many :notifications, dependent: :destroy
  belongs_to :user
  belongs_to :room
end


app/models/room.rb

class Room < ApplicationRecord
  has_many :notifications, dependent: :destroy
  has_many :messages, dependent: :destroy
  has_many :entries, dependent: :destroy


app/models/notification.rb

class Notification < ApplicationRecord
  default_scope -> { order(created_at: :desc) }
  belongs_to :room, optional: true
  belongs_to :message, optional: true
  belongs_to :visitor, class_name: 'User', optional: true
  belongs_to :visited, class_name: 'User', optional: true
end


create_notification_dmメソッドの定義

roomモデルの通知データを保存するためのメソッドを実装していきます。

app/models/room.rb

class Room < ApplicationRecord
  has_many :notifications, dependent: :destroy
  has_many :messages, dependent: :destroy
  has_many :entries, dependent: :destroy


  def create_notification_dm(current_user, message_id)
    # ルームに関連する全てのエントリーレコードを取得
    @multiple_entry_records = Entry.where(room_id: id).where.not(user_id: current_user.id)
    # ルームに関連する単一のエントリーレコードを取得
    @single_entry_record = @multiple_entry_records.find_by(room_id: id)
    
    # メッセージの送信者以外のユーザーに通知を作成
    notification = current_user.active_notifications.build(
      room_id: id,
      message_id: message_id,
      visited_id: @single_entry_record.user_id,
      action: 'dm'
    )

    notification.save if notification.valid?
  end

end


viewページ

app/views/notifications/_notification.html.erb
<% notifications.each do |notification| %>
  <% visitor = notification.visitor %>
  <% visited = notification.visited %>
  <div class="col-md-12 mx-auto notification-container">
    <div class="notification-box align-items-center">
      <div class="box16">
       <p><!-- 通知の種類に応じて表示内容を切り替え -->
      <% case notification.action when 'follow' then %>

      <!-- フォロー通知の場合 -->
        <strong><%= visitor.name %></strong>さんがあなたをフォローしました
      
      <!-- DMが送られた通知の場合 -->
      <% when 'dm' then %>
      <p>あなたに</p>
        <h5><i class="fas fa-envelope"></i>DMを送りました</h5>
        <span>メッセージ内容:</span>
          <%= truncate(notification.message.message, length: 20, omission: '... (一部表示)') %>
        <%= link_to room_path(notification.room) do %>
          <h4>DMの送信画面に移動</h4>
        <% end %>
        <hr>

      <!-- 投稿がいいねされた通知の場合 -->
      <% when 'favorite_post' then %>
        <%= link_to post_path(notification.post) do %>
          <strong><%= visitor.name %></strong>さんが<strong><%= truncate(notification.post.text, length: 10) %></strong>の投稿にいいねしました
        <% end %>

      <!-- コメントが投稿された通知の場合 -->
      <% when 'post_comment' then %>
        <!-- 自分自身の投稿へのコメントの場合 -->
        <% if notification.post.user_id == visited.id %>
          <%= link_to post_path(notification.post) do %>
            <strong><%= visitor.name %></strong>さんが<strong><%= truncate(notification.post.text, length: 10) %></strong>の投稿にコメントしました
            <% post_comment = PostComment.find_by(id: notification.post_comment_id) %>
            <div class="notification-comment">
              <%= truncate(post_comment&.comment, length: 30) %>
            </div>
          <% end %>

        <!-- 投稿者が異なり自身がコメントした投稿に他のユーザーがコメントした場合 -->
        <% else %>
          <span>
            <%= link_to post_path(notification.post) do %>
              <strong><%= visitor.name %></strong>さんが<strong><%= notification.post.user.name + 'さんの投稿' %></strong>にコメントしました
              <% post_comment = PostComment.find_by(id: notification.post_comment_id) %>
              <div class="notification-comment">
                <%= truncate(post_comment&.comment, length: 30) %>
              </div>
            <% end %>
          </span>
        <% end %>
      <% end %></p>
      </div>
    </div>
    <div class="small text-muted text-right">
      <%= notification.created_at.in_time_zone('Tokyo').strftime('%Y-%m-%d') %>
    </div>
  </div>
<% end %>

他の時と場合分けを行っていたためここにDM通知を追加しました。

Discussion