Zenn
🐙

[Rails]通知機能①(ポリモーフィック関連,コールバック)

2025/03/19に公開

ポリモーフィック関連(Polymorphic Association)

1つのテーブルが複数の異なるテーブルと関連を持てる仕組み。

通知機能(Notification)の場合、通知の対象が「コメント」だったり、「投稿」だったり、色々なもので通知する。
コメントも投稿もいいねもフォローも、通知する可能性がある。

この場合、post_idcomment_id など、各テーブルごとにカラムを作成する必要があるがけど、ポリモーフィック関連を使えば1つのカラムで複数のテーブルに対応できる。


以下、実装手順。

1. モデルとマイグレーションの作成

通知(Notification)モデルを作成

rails g model Notification user:references notifiable:polymorphic read:boolean

マイグレーションファイル

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によって
notifiable_idnotifiable_type の2つのカラムが自動で作成される。

id user_id notifiable_id notifiable_type read
1 1 10 "Post" false
2 2 5 "Comment" false
t.integer :user_id
t.index :user_id
  • notifiable_id: 関連するデータのID( Post や Comment の ID )
  • notifiable_type: 関連するテーブル名("Post" や "Comment")(どのモデル(テーブル)のデータか )

2. モデルの設定

通知(Notification)モデル

class Notification < ApplicationRecord
  belongs_to :user
  belongs_to :notifiable, polymorphic: true
end

投稿(Post)モデル

class Post < ApplicationRecord
  has_many :notifications, as: :notifiable, dependent: :destroy
end

コメント(Comment)モデル

class Comment < ApplicationRecord
  has_many :notifications, as: :notifiable, dependent: :destroy
end

3. 通知の作成

コールバック(Callback)

ActiveRecord の特定のタイミングで自動的に処理を実行する仕組み。
レコードが作成・更新・削除された時、特定のメソッドを自動で実行できる。

コールバックは、ActiveRecordに元からある機能で、データを作成したり更新したりするタイミングで自動で行われる機能。
コールバックにはいくつか種類があって、それぞれ実行されるタイミングが異なる。

ActiveRecordとは

モデルは、ActiveRecord を継承している。

ActiveRecord

データベースとやりとりするための主要クラスで、以下の機能を持つ。

  • データベースのCRUD操作(Create, Read, Update, Delete)
  • SQL文の生成と実行
  • バリデーションやコールバックのサポート

https://zenn.dev/eliri/articles/f8b1b95c2bd2f9#モデル-(model)

コールバックの種類

順序 コールバック名 実行タイミング
1 before_validation バリデーション実行前
2 after_validation バリデーション実行後
3 before_save 保存処理の実行前
4 around_save 保存処理の実行前後
5 before_create 新規作成時の保存処理前
6 around_create 新規作成時の保存処理前後
7 after_create 新規作成時の保存処理後
8 after_save 保存処理後(作成と更新両方で実行)
9a after_commit 保存処理後(作成と更新両方で実行・ロールバックしない)
9b after_rollback ロールバック時に実行

https://railsguides.jp/active_record_callbacks.html

今回は「いいね(Favorite)されたときに通知を作成する」という処理なので、「作成時のみ実行される」 after_create を使う。

下記は、本を作成したタイミングでフォローしているユーザーに通知するという流れ。
book.rb

  after_create do
    user.followers.each do |follower|
      notifications.create(user_id: follower.id)
    end
  end

同時にいいね機能とフォロー・フォロワー機能の追加も進めてしまったので、今日はひとまずここまで!

参考文献

https://techlife.cookpad.com/entry/2023/04/13/141200

Discussion

ログインするとコメントできます