Skip to content

3クラス分newspaperの利用をActiveSupport::Notificationsに置き換える#8968

Merged
komagata merged 3 commits intomainfrom
chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier
Jul 28, 2025
Merged

3クラス分newspaperの利用をActiveSupport::Notificationsに置き換える#8968
komagata merged 3 commits intomainfrom
chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier

Conversation

@jun-kondo
Copy link
Copy Markdown
Contributor

@jun-kondo jun-kondo commented Jul 20, 2025

Issue

概要

下記の3クラスの実装を、newspaperからActiveSupport::Notificationsに置き換えました。

  • ReportNotifier
    • 日報投稿時に通知を行うクラス
  • WorkNotificationDestroyer
    • 投稿したポートフォリオをユーザーが削除したときに、ポートフォリオ投稿の通知を削除するクラス
  • InquiryNotifier
    • 問い合わせフォームから問い合わせがあった際、管理者側に通知を行うクラス

変更確認方法

事前準備

ブランチをローカルに取り込み切り替え

git fetch origin chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier
git checkout chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier

ローカルサーバーの立ち上げ

rails db:reset
bin/setup
foreman start -f Procfile.dev

ログインユーザーを何度も切り替えるのでany_loginの機能を使うことをおすすめします。
下記使用ユーザーのログインネーム。パスワードはいずれもtesttest

  • kimura
  • hajime
  • mentormentaro(メンター)
  • komagata(メンター、管理者)

ReportNotifierでのイベント動作確認

ReportNotifierでのイベント動作確認

  • ReportNotifierはユーザーが日報投稿したときに通知を行うクラス
  • 本文でメンションされた場合、相手側に通知が行くので以下の手順で確認します

http://localhost:3000/

  1. hajimeでログインし、日報を今日の日付で作成、本文に@kimura を含めて提出
  2. kimuraでログインする
  3. 通知一覧の最上部に「hajimeさんの日報「(任意のタイトル)」でhajime さんからメンションが来ました。」の文言の通知があるか確認する
WorkNotificationDestroyerでのイベント動作確認

WorkNotificationDestroyerでのイベント動作確認

  • WorkNotificationDestroyerは投稿したポートフォリオをユーザーが削除したときに、ポートフォリオ投稿の通知を削除するクラス
  • 投稿されたポートフォリオが削除されると、当該ポートフォリオの通知が通知欄から消えることを以下の手順で確認します

http://localhost:3000/

  1. kimuraでログイン
  2. ポートフォリオを新規追加
    • URL、リリースブログURLが必須入力なのでhttp://example.comで入力
  3. メンターか管理者でログインして通知欄の先頭にkimuraがポートフォリオを追加した通知があることを確認
  4. kimuraでログインして、2.で追加したポートフォリオを削除
  5. メンターか管理者でログインして当該のポートフォリオ追加の通知が消えていることを確認
InquiryNotifierでのイベント動作確認

InquiryNotifierでのイベント動作確認

  • InquiryNotifierは問い合わせフォームから問い合わせがあった際、管理者側に通知を行うクラス
  • 以下の手順で問い合わせ通知を管理者が受け取れているか確認します

http://localhost:3000/

  1. ログインしていればログアウトする
  2. トップページ下部のお問い合わせリンクをクリック、もしくは/inquiry/newでお問い合わせフォームのページに移動
  3. 問い合わせを送信
  4. 管理者でログインして通知欄に先ほど送信した問い合わせの通知があることを確認

Screenshot

内部的な変更なのでスクリーンショットはありません。

Summary by CodeRabbit

  • リファクタリング

    • 通知イベントの仕組みを変更し、内部的に新しいイベント通知方式を利用するようになりました。
  • その他

    • これまでの通知機能は引き続き動作しますが、内部のイベント処理方法が変更されています。エンドユーザーの操作や画面には影響ありません。

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 20, 2025

Walkthrough

イベント通知の仕組みを Newspaper.publish から ActiveSupport::Notifications.instrument へ移行し、対応するサブスクライバー(Notifier)も ActiveSupport::Notifications の標準的な5引数シグネチャに対応しました。また、初期化ファイルでのイベント購読設定も ActiveSupport::Notifications 用に変更され、Newspaper 経由の購読は削除されました。

Changes

ファイル・グループ 変更内容概要
app/controllers/inquiries_controller.rb
app/controllers/works_controller.rb
イベント通知を Newspaper.publish から ActiveSupport::Notifications.instrument に置換
app/models/inquiry_notifier.rb
app/models/report_notifier.rb
app/models/work_notification_destroyer.rb
call メソッドのシグネチャを1引数から5引数(ActiveSupport::Notifications仕様)に変更
config/initializers/active_support_notifications.rb 各Notifierを新しいイベント名で ActiveSupport::Notifications にサブスクライブ追加
config/initializers/newspaper.rb Newspaper経由の3つのイベント購読(ReportNotifier, WorkNotificationDestroyer, InquiryNotifier)を削除

Sequence Diagram(s)

sequenceDiagram
    participant Controller as Controller (Inquiries/Works)
    participant ActiveSupport as ActiveSupport::Notifications
    participant Notifier as Notifier (各種 Notifierクラス)

    Controller->>ActiveSupport: instrument('came.inquiry' or 'work.destroy', payload)
    ActiveSupport->>Notifier: call(_name, _started, _finished, _unique_id, payload)
    Notifier->>Notifier: payloadを処理
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • komagata

Poem

ぴょんぴょん跳ねてお知らせ運ぶ、
新聞うさぎは今日で引退、
ActiveSupportの森でイベント響く、
サブスクライバーたちも新しい歌、
これからも通知はしっかりお届け、
うさぎのしっぽでリファクタ祝う!
 ∩_∩
(・x・)ノ✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 RuboCop (1.76.1)
app/controllers/works_controller.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:309:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader.rb:66:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

app/controllers/inquiries_controller.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:309:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader.rb:66:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

app/models/inquiry_notifier.rb

rubocop-minitest extension supports plugin, specify plugins: rubocop-minitest instead of require: rubocop-minitest in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
rubocop-capybara extension supports plugin, specify plugins: rubocop-capybara instead of require: rubocop-capybara in /.rubocop.yml.
For more information, see https://docs.rubocop.org/rubocop/plugin_migration_guide.html.
Unable to find gem rubocop-fjord; is the gem installed? Gem::MissingSpecError
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:309:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:84:in block (2 levels) in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:82:in block in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in each_pair'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_loader.rb:66:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/config_store.rb:29:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:160:in act_on_options'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:47:in block in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:81:in profile_if_needed'
/var/lib/gems/3.1.0/gems/rubocop-1.77.0/lib/rubocop/cli.rb:43:in run' /var/lib/gems/3.1.0/gems/rubocop-1.77.0/exe/rubocop:19:in <top (required)>'
/usr/local/bin/rubocop:25:in load' /usr/local/bin/rubocop:25:in

'

  • 3 others

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d8c0a4 and ba4dc91.

📒 Files selected for processing (7)
  • app/controllers/inquiries_controller.rb (1 hunks)
  • app/controllers/works_controller.rb (1 hunks)
  • app/models/inquiry_notifier.rb (1 hunks)
  • app/models/report_notifier.rb (1 hunks)
  • app/models/work_notification_destroyer.rb (1 hunks)
  • config/initializers/active_support_notifications.rb (1 hunks)
  • config/initializers/newspaper.rb (0 hunks)
💤 Files with no reviewable changes (1)
  • config/initializers/newspaper.rb
🚧 Files skipped from review as they are similar to previous changes (6)
  • config/initializers/active_support_notifications.rb
  • app/controllers/inquiries_controller.rb
  • app/controllers/works_controller.rb
  • app/models/work_notification_destroyer.rb
  • app/models/report_notifier.rb
  • app/models/inquiry_notifier.rb
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build_and_test
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@jun-kondo jun-kondo self-assigned this Jul 21, 2025
@jun-kondo jun-kondo marked this pull request as ready for review July 21, 2025 01:47
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
app/models/work_notification_destroyer.rb (1)

5-8: エラーハンドリングの追加を検討

現在の実装ではpayload[:work]nilの場合や、work.idが期待される形式でない場合のエラーハンドリングがありません。

 def call(_name, _started, _finished, _unique_id, payload)
   work = payload[:work]
+  return if work.nil?

   Notification.where(link: "/works/#{work.id}").destroy_all
 end
app/models/inquiry_notifier.rb (1)

10-14: 送信者ユーザーの存在チェックを追加することを検討

現在の実装ではNOTIFICATION_SENDER_NAMEで指定されたユーザーが存在しない場合、sendernilになる可能性があります。

 sender = User.find_by(login_name: NOTIFICATION_SENDER_NAME)
+return if sender.nil?
+
 User.admins.each do |receiver|
   ActivityDelivery.with(inquiry:, receiver:, sender:).notify(:came_inquiry)
 end
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6262861 and 9d8c0a4.

📒 Files selected for processing (8)
  • app/controllers/inquiries_controller.rb (1 hunks)
  • app/controllers/reports_controller.rb (2 hunks)
  • app/controllers/works_controller.rb (1 hunks)
  • app/models/inquiry_notifier.rb (1 hunks)
  • app/models/report_notifier.rb (1 hunks)
  • app/models/work_notification_destroyer.rb (1 hunks)
  • config/initializers/active_support_notifications.rb (1 hunks)
  • config/initializers/newspaper.rb (0 hunks)
💤 Files with no reviewable changes (1)
  • config/initializers/newspaper.rb
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rb

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

🧠 Learnings (4)
📓 Common learnings
Learnt from: reckyy
PR: fjordllc/bootcamp#8356
File: app/models/notification.rb:45-47
Timestamp: 2025-07-15T12:58:02.735Z
Learning: fjordllc/bootcampプロジェクトの`app/models/notification.rb`において、`training_completed`通知種別は`TARGETS_TO_KINDS`ハッシュに含めない設計になっている。これは`training_completed`が通知一覧のフィルタ対象ではないためで、意図的な設計判断である。
config/initializers/active_support_notifications.rb (1)
Learnt from: reckyy
PR: fjordllc/bootcamp#8356
File: app/models/notification.rb:45-47
Timestamp: 2025-07-15T12:58:02.735Z
Learning: fjordllc/bootcampプロジェクトの`app/models/notification.rb`において、`training_completed`通知種別は`TARGETS_TO_KINDS`ハッシュに含めない設計になっている。これは`training_completed`が通知一覧のフィルタ対象ではないためで、意図的な設計判断である。
app/controllers/works_controller.rb (1)
Learnt from: mousu-a
PR: fjordllc/bootcamp#8566
File: app/notifiers/activity_notifier.rb:357-373
Timestamp: 2025-07-01T04:30:19.565Z
Learning: matching_pair_workメソッドは、ペア確定時に送信される通知のため、pair_work.buddy_idは必ず存在することがビジネスロジックで保証されている。そのため、User.find(pair_work.buddy_id)でのエラーハンドリングは不要。
app/models/work_notification_destroyer.rb (1)
Learnt from: reckyy
PR: fjordllc/bootcamp#8356
File: app/models/notification.rb:45-47
Timestamp: 2025-07-15T12:58:02.735Z
Learning: fjordllc/bootcampプロジェクトの`app/models/notification.rb`において、`training_completed`通知種別は`TARGETS_TO_KINDS`ハッシュに含めない設計になっている。これは`training_completed`が通知一覧のフィルタ対象ではないためで、意図的な設計判断である。
🔇 Additional comments (11)
app/models/report_notifier.rb (1)

4-4: ActiveSupport::Notificationsの仕様に適合したメソッドシグネチャに正しく更新されています

メソッドシグネチャがActiveSupport::Notificationsのsubscriberインターフェースに適合するよう正しく更新されています。使用しないパラメータにアンダースコアのプレフィックスを付けているのも良い実装です。

app/controllers/inquiries_controller.rb (1)

16-16: NewspaperからActiveSupport::Notificationsへの移行が正しく実装されています

イベント発行方法がNewspaper.publishからActiveSupport::Notifications.instrumentに正しく変更され、イベント名もドット記法の'came.inquiry'に統一されています。

config/initializers/active_support_notifications.rb (1)

9-12: 新しいActiveSupport::Notificationsサブスクリプションが正しく追加されています

Railsアプリケーションリローダーブロック内に適切に配置され、イベント名もコントローラーで使用されているものと一致しています。既存のサブスクリプションパターンに従った実装です。

app/controllers/works_controller.rb (2)

47-47: work.destroyイベントの移行が正しく実装されています

Newspaper.publishからActiveSupport::Notifications.instrumentへの変更が正しく実装されています。


30-30: Newspaper.publish(:work_create) の使用は意図的です

config/initializers/newspaper.rb に以下のようにサブスクライブ定義が残っているため、create アクションで Newspaper.publish(:work_create, …) を呼び出しているのは仕様どおりです。移行漏れではなく、work_create イベントはまだ Newspaper 経由で通知される設計となっています。

  • config/initializers/newspaper.rb:
    Newspaper.subscribe(:work_create, WorkNotifier.new)

よって、このまま Newspaper.publish を使い続けて問題ありません。

app/controllers/reports_controller.rb (3)

62-62: report.createイベントの追加が正しく実装されています

ActiveSupport::Notifications.instrumentを使用した新しいイベント発行が適切に追加されています。


79-79: report.updateイベントの追加が正しく実装されています

ActiveSupport::Notifications.instrumentを使用した新しいイベント発行が適切に追加されています。


62-64: Newspaper.publishとActiveSupport::Notificationsの並行発行は移行フェーズで意図的かご確認ください

現在、app/controllers/reports_controller.rb の以下箇所で両方のイベント発行が残っています。これは意図的な移行期間中の実装でしょうか?

• create アクション(62–64行目)
• update アクション(79–81行目)

加えて以下点をご確認・ご検討ください:

  • 移行完了後に Newspaper.publish を削除するタイミング/計画の有無
  • 全イベントリスナーのActiveSupportへの移行状況
  • README等ドキュメントへの移行方針の明記
app/models/work_notification_destroyer.rb (1)

4-4: ActiveSupport::Notificationsの標準的なsubscriberインターフェースに正しく対応

メソッドシグネチャがActiveSupport::Notificationsの標準形式に正しく更新されています。未使用パラメータにアンダースコアプレフィックスを使用している点も適切です。

app/models/inquiry_notifier.rb (2)

6-6: ActiveSupport::Notificationsのsubscriberインターフェースに正しく適応

メソッドシグネチャがActiveSupport::Notificationsの標準形式に適切に更新されています。


8-8: 適切なnilチェック

inquiryオブジェクトのnilチェックが適切に実装されており、防御的プログラミングの良い例です。

@jun-kondo jun-kondo requested a review from matuaya July 21, 2025 02:51
@jun-kondo
Copy link
Copy Markdown
Contributor Author

@matuaya
お疲れ様ですー
レビューお願いしたいのですが、ご都合如何でしょうか?🙇‍♂️

@jun-kondo
Copy link
Copy Markdown
Contributor Author

@coderabbitai

  1. WorkNotificationDestroyerクラス呼び出されるのがapp/controllers/works_controller.rbdestroyアクションが実行されたときです。idが不正であればbefore_action :set_my_work
    の時点でエラーが発生します。よってWorkNotificationDestroyerでもエラーハンドリングする必要はないと思います。

  2. app/models/inquiry_notifier.rbのエラーハンドリングについて、指定されているのは管理者ユーザーであり、そのユーザーがいないということは想定されていないと思います。必ずいるユーザーであることがわかっているのでエラーハンドリングは必要ないのではないと思います。

Actionable comments posted: 0

🧹 Nitpick comments (2)

app/models/work_notification_destroyer.rb (1)> 5-8: エラーハンドリングの追加を検討

現在の実装ではpayload[:work]nilの場合や、work.idが期待される形式でない場合のエラーハンドリングがありません。

 def call(_name, _started, _finished, _unique_id, payload)
   work = payload[:work]
+  return if work.nil?

   Notification.where(link: "/works/#{work.id}").destroy_all
 end

app/models/inquiry_notifier.rb (1)> 10-14: 送信者ユーザーの存在チェックを追加することを検討

現在の実装ではNOTIFICATION_SENDER_NAMEで指定されたユーザーが存在しない場合、sendernilになる可能性があります。

 sender = User.find_by(login_name: NOTIFICATION_SENDER_NAME)
+return if sender.nil?
+
 User.admins.each do |receiver|
   ActivityDelivery.with(inquiry:, receiver:, sender:).notify(:came_inquiry)
 end

📜 Review details

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 23, 2025

Tip

For best results, initiate chat on the files or code changes.

@jun-kondo さん、詳細なご説明ありがとうございます!

  1. WorkNotificationDestroyerについて:before_action :set_my_workでのバリデーションが先に実行されるため、不正なIDの場合はそこでエラーになるというロジックを理解しました。確かにWorkNotificationDestroyerレベルでのエラーハンドリングは不要ですね。

  2. InquiryNotifierについて:NOTIFICATION_SENDER_NAMEで指定される管理者ユーザーは必ず存在することが前提の設計であることを理解しました。システムの前提条件として管理者ユーザーの存在が保証されているのであれば、エラーハンドリングは確かに不要だと思います。

このような業務ロジックの背景を教えていただき、とても参考になりました。今後のレビューでより適切な提案ができるよう、この情報を記録させていただきます。


✏️ Learnings added
Learnt from: jun-kondo
URL: https://github.com/fjordllc/bootcamp/pull/8968

Timestamp: 2025-07-23T21:11:21.775Z
Learning: fjordllc/bootcampプロジェクトの`app/models/work_notification_destroyer.rb`において、このクラスは`app/controllers/works_controller.rb`の`destroy`アクションから呼び出され、`before_action :set_my_work`でIDの妥当性チェックが事前に行われるため、payloadのworkオブジェクトは常に有効であることが保証されている。そのためエラーハンドリングは不要。

Learnt from: jun-kondo
URL: https://github.com/fjordllc/bootcamp/pull/8968

Timestamp: 2025-07-23T21:11:21.775Z
Learning: fjordllc/bootcampプロジェクトの`app/models/inquiry_notifier.rb`において、`NOTIFICATION_SENDER_NAME`で指定される管理者ユーザーは必ず存在することがシステムの前提条件として保証されているため、senderがnilになることは想定されておらず、エラーハンドリングは不要である。

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.


🧠 Learnings used
Learnt from: reckyy
PR: fjordllc/bootcamp#8356
File: app/models/notification.rb:45-47
Timestamp: 2025-07-15T12:58:02.735Z
Learning: fjordllc/bootcampプロジェクトの`app/models/notification.rb`において、`training_completed`通知種別は`TARGETS_TO_KINDS`ハッシュに含めない設計になっている。これは`training_completed`が通知一覧のフィルタ対象ではないためで、意図的な設計判断である。

Learnt from: jun-kondo
PR: fjordllc/bootcamp#8977
File: app/controllers/reports_controller.rb:63-63
Timestamp: 2025-07-23T20:31:13.816Z
Learning: fjordllc/bootcampプロジェクトの`app/controllers/reports_controller.rb`において、`create`と`update`アクションは両方とも`@report.save_uniquely`を使用し、同じ`:report_save`イベントと`'report.save'`イベントを発行する。これは両方とも本質的に「レポートの保存」操作であり、作成と更新を区別する必要がないためである。

Learnt from: mousu-a
PR: fjordllc/bootcamp#8566
File: app/notifiers/activity_notifier.rb:357-373
Timestamp: 2025-07-01T04:30:19.565Z
Learning: matching_pair_workメソッドは、ペア確定時に送信される通知のため、pair_work.buddy_idは必ず存在することがビジネスロジックで保証されている。そのため、User.find(pair_work.buddy_id)でのエラーハンドリングは不要。

@jun-kondo jun-kondo force-pushed the chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier branch from 9d8c0a4 to ba4dc91 Compare July 24, 2025 10:14
@matuaya
Copy link
Copy Markdown
Contributor

matuaya commented Jul 24, 2025

@jun-kondo
返信遅れて大変申し訳ありません🙇‍♀️
レビュー承りました🙇‍♀️

@jun-kondo
Copy link
Copy Markdown
Contributor Author

@matuaya
ありがとうございます🙇‍♂️
急ぎませんので、どうぞよろしくお願い致しますー🙏

Copy link
Copy Markdown
Contributor

@matuaya matuaya left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確認しました!
Approveさせていただきます😊

@jun-kondo
Copy link
Copy Markdown
Contributor Author

@matuaya
レビューありがとうございましたー🙏

@komagata
こちらチームメンバーから承認頂きましたのでレビューよろしくお願い致します🙇‍♂️

Copy link
Copy Markdown
Member

@komagata komagata left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

確認させて頂きました。OKです〜🙆‍♂️

@komagata komagata merged commit e102d4c into main Jul 28, 2025
8 checks passed
@komagata komagata deleted the chore/replace-newspaper-with-activesupport_notifications-in-reportnotifier-worknotificationdestroyer-inquirynotifier branch July 28, 2025 07:04
@github-actions github-actions bot mentioned this pull request Jul 28, 2025
87 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants