dev.toの通知
ソースコードは特に注意がない場合dev.toのものをそのままコピペしているのでライセンスはdev.toのライセンスに従います。
テーブル全容
code:ruby
create_table "notifications", id: :serial, force: :cascade do |t|
t.string "action"
t.datetime "created_at", null: false
t.jsonb "json_data"
t.integer "notifiable_id"
t.string "notifiable_type"
t.datetime "notified_at"
t.bigint "organization_id"
t.boolean "read", default: false
t.datetime "updated_at", null: false
t.integer "user_id"
t.index "created_at", name: "index_notifications_on_created_at" t.index "json_data", name: "index_notifications_on_json_data", using: :gin t.index "notified_at", name: "index_notifications_on_notified_at" t.index "user_id", name: "index_notifications_on_user_id" end
テーブルを見てわかること
通知可能なオブジェクトが notifiable に入っている
通知可能なオブジェクトに対してどのような行いがあったのか action に入っている
通知に表示するのに必要な詳細な情報は json_data に突っ込む器のデカさ、serializeではなくJSON型を使っている
既読かどうかは各通知ごとに管理されている
通知が作成された日時と通知した日時は別で管理している
個人向けの通知と組織向けの通知がありどちらも同じテーブルで管理されている
リソース全容
code:ruby
resources :notifications, only: :index get "/notifications/:filter" => "notifications#index"
get "/notifications/:filter/:org_id" => "notifications#index"
namespace :notifications do
resources :counts, only: :index end
わかること
通知は作れない、他のリソースの作成などに伴って作成されるもの
通知は一覧できる
通知は通知対象によって絞り込みできる
通知は組織によって絞り込みできる
通知を読んだ、を作成できる
ここで作成している「読んだ」リソースは永続化されていない
通知は数えることができる
未読を返している
モデル
通知周りは Notifications 以下の名前空間にまとめられている
通知はワーカーにより送られる、モデルのメソッドはWorkerをエンキューするだけ
ワーカーはガードをかけたあとサービス層に通知の作成を依頼、 Send という名前のクラス
リアクションとフォローに関しては既存の通知がある場合その通知の内容が更新される
ある程度たまった通知はバッチで削除される
通知の役割を終えたことを考えると自然
通知によっては全員に送っていないのが面白い、 app/services/notifications/notifiable_action/send.rb から抜粋
code:ruby
# followers is an array and not an activerecord object
# followers can occasionally be nil because orphaned follows can possibly exist in the db (for now)
followers.sort_by(&:updated_at).reverse0..10_000.each do |follower| view
ページのロード時に通知ページがpreloadで読み込まれる流れ
app/assets/javascripts/base.js.erb で
initializeBaseApp が呼ばれる
initializePageが呼ばれる
app/assets/javascripts/initializePage.js.erb で
callInitalizersが呼ばれる
initNotifications が呼ばれる
app/assets/javascripts/initializers/initNotifications.js で
fetchNotificationsCount が呼ばれるが実際ここでは通知数を取ってきているわけではない
ページのロード時に通知数をロードする流れ
app/views/layouts/_top_bar.html.erb の中から /notifications/count が呼ばれその結果が表示される
通知を開いた際の流れ
/notifications/readsリソースが作成される
通知を開いた際の流れ
/notifications の内容が表示される
記事を開くとリアクションボタンが表示されておりリアクションを付けると通知が作成される
わからないこと
app/labor 層があり何をしているのかよくわからない