通知機能実装時の困りごと
内容
PF作成の時にメンターさんに教えて頂いたことをいつもで引き出せるように書いておこうと思います。
通知作成時にエラー解決で困った事を記載します。
***_create_notifications.rb
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
t.references :notifiable, polymorphic: true, null: false
このように書く事で、notifiableカラムが複数の異なるモデルと関連付けられます。同じ外部キーを複数の異なるモデルに対して使えます。
notification.rb
class Notification < ApplicationRecord
# モデルの中でxxx_pathメソッドを使用するために必要
include Rails.application.routes.url_helpers
belongs_to :user
belongs_to :notifiable, polymorphic: true
# 通知の表示
def message
case notifiable_type
:
:
when "StudyReview"
"<i class='fa-solid fa-book-open'></i> #{notifiable.user.name}さんがレビューを投稿しました".html_safe
end
end
# 通知の遷移先
def notifiable_path
case notifiable_type
:
:
when "StudyReview"
study_study_review_path(study_id: notifiable.study_id, id: notifiable.id)
end
end
end
belongs_to :user
通知がどのユーザーに属するかを示しています
belongs_to :notifiable, polymorphic: true
通知が異なる種類のリソースと関連していることを示しています
通知メッセージを生成するためのメソッド(message)、通知がクリックされたときに遷移すべきパスを生成するメソッド(notifiable_path)を作成します。
study_review.rb
class StudyReview < ApplicationRecord
belongs_to :user
belongs_to :study
has_many :notification, as: :notifiable, dependent: :destroy
# レビュー作成時に各フォロワーに通知を作成
after_create do
user.followers.each do |follower|
notification = follower.notifications.build(notifiable: self)
notification.save
end
end
end
大分端折ってますが、ここが本題で、after_createでstudy_reviewが作成された時に、通知(notification)を作成するようにしています。
user.followers.each do |follower|
notification = follower.notifications.build(notifiable: self)
notification.save
end
新しい通知が作成された後に、通知を受け取るユーザー(フォロワー)すべてにその通知を複製するようにしてます。
今回間違えたのが、一人に対して通知を作成するではなく、複数人(フォロワー)全てに通知を作成しているところで、study_reviewに対して通知は複数作られる事になります。
そのためアソシエーションは、has_many :notification, as: :notifiable, dependent: :destroy となるところを、has_one :notification, as: :notifiable, dependent: :destroy と記載してました。
has_oneでは、study_reviewを削除した時に、複製した通知を参照できず、通知データを一緒に削除できず、エラーになってました。
まとめ
そもそもエラーを見つけられたのが、偶然だったので、エラーが潜んでないか入念にチェックしないといけないと思いました。
Discussion