🍣
chat機能に通知機能を持たせる
今回、chat機能に対して、通知機能をポリモーフィックで作成しました。
ポリモーフィックとはなに?
簡単にいうと、カラムを使いまわせるよ、的なニュアンスのもの。
まずは、通知モデルを作成していきます。
下記のコマンドを入力して、通知モデルを作成してください。
$ rails g model Notification user:references notifiable:references{polymorphic} read:boolean
ここでのポイントは、referencesを使用している点です。
referencesを指定すると、モデル同士の関連付けを行う場合に通常必要になるNOT NULL制約や、外部キー制約といったオプションをマイグレーションファイルに自動的に設定します。
class CreateNotifications < ActiveRecord::Migration[6.1]
def change
create_table :notifications do |t|
t.references :user, null: false, foreign_key: true
t.references :notifiable, polymorphic: true, null: false
t.boolean :read, default: false, null: false # 追記
t.timestamps
end
end
end
で、migrateをかけてください。
notificationmodel
class Notification < ApplicationRecord
belongs_to :user
belongs_to :notifiable, polymorphic: true
end
chatmodel
class Chat < ApplicationRecord
belongs_to :user
belongs_to :room
has_many :notifications, as: :notifiable, dependent: :destroy
after_create_commit :create_notifications
def create_notifications
# self.user_id は、このチャットを作成したユーザーのIDです。
self.room.user_rooms.where.not(user_id: self.user_id).each do |user|
# ここで各ユーザーに対して通知を作成します。
Notification.create!(
user_id: user.user_id, # 通知を受けるユーザー
notifiable: self, # 関連するチャット
)
end
end
end
好きなところにこれを追加します。
<li class="dropdown">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Notification
<span class="badge badge-danger"><%= current_user.notifications.where(read: false).count %></span>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<% if current_user.notifications.where(read: false).any? %>
<small class="dropdown-item disabled">直近5件の未読の通知を表示しています</small>
<% current_user.notifications.where(read: false).limit(5).order(created_at: :desc).each do |notification| %>
<%= link_to notification_message(notification), notification_path(notification), method: :patch, class: "dropdown-item" %>
<% end %>
<% else %>
<span class="dropdown-item disabled">未読の通知はありません</span>
<% end %>
</div>
</li>
次回はコントローラーと、ルート設定を公開します。
チャット機能の作成手順はこのリンクを参照してください
Discussion