Skip to content

メンターメモに作成者と作成時間を追加し、1対多の関係に変更#10121

Open
matuaya wants to merge 29 commits into
mainfrom
feature/add-author-and-timestamp-to-mentor-memos
Open

メンターメモに作成者と作成時間を追加し、1対多の関係に変更#10121
matuaya wants to merge 29 commits into
mainfrom
feature/add-author-and-timestamp-to-mentor-memos

Conversation

@matuaya

@matuaya matuaya commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Issue

概要

今まではメンターメモはUserの属性として扱われていたので作成者や作成日時などの情報をもつことはできなかったが、本PRでメンターメモとUserを1対多の関係になるように再設計し、個々のデータとして管理できるように変更した。

変更確認方法

  1. feature/add-author-and-timestamp-to-mentor-memosをローカルに取り込む
  2. komagataでログインし、任意のユーザーのプロフィールに移動する
  3. プロフィールの右下にある「メンター向けユーザーメモ」にメモを追加し以下を確認する
  • プレビューが正常に表示されること
  • メモの編集ができること
  • メモの削除ができること
  • 作成者名と作成日時が表示されること
  1. mentormentaroでログインし、先ほどと同じユーザーのプロフィールに移動する
  2. komagataで作成したメモの編集ボタンと削除ボタンが表示されず、メモの編集と削除ができないことを確認する

Screenshot

変更前

スクリーンショット 2026-06-25 2 22 09

変更後

スクリーンショット 2026-06-25 2 24 07

Flakewatch Report

Flakewatch Report

Summary by CodeRabbit

  • 新機能
    • ユーザーごとにメンター用メモを追加・編集・削除できるようになりました。
    • メンター用メモの一覧表示(作成者・作成日時)と、Markdownプレビュー付きの編集UIを追加しました。
  • 改善
    • 編集中はプレビューを切り替えられ、保存・キャンセルの操作で状態が適切に反映されます。
    • 権限に応じて操作可否を制御し、管理者は他者メモも編集/削除できます。

Review App

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

mentor_memos の保存先とモデルを追加し、API を create/update/destroy 対応へ拡張しました。各画面で受信メモ一覧を表示するようにし、編集・追加・削除の UI と関連テスト、スタイル、JS エントリも更新しています。

Changes

メンターメモ管理機能

Layer / File(s) Summary
DBスキーマとモデル関連
db/migrate/20260126070916_create_mentor_memos.rb, db/schema.rb, app/models/mentor_memo.rb, app/models/user.rb
mentor_memos テーブルを新規作成し、MentorMemo モデルに recipient/writer の関連と body の必須バリデーションを追加。User に受信/作成メモの関連を追加。
APIルーティングとCRUD/認可
config/routes/api.rb, app/controllers/api/mentor_memos_controller.rb
mentor_memosusers 配下へ移し、create/update/destroy と認可・取得・パラメータ処理を追加。
各コントローラーでの取得とビュー差し替え
app/controllers/users_controller.rb, app/controllers/products_controller.rb, app/controllers/reports_controller.rb, app/controllers/talks_controller.rb, app/views/users/_user_mentor_memos.html.slim, app/views/users/_mentor_memo.html.slim, app/views/users/show.html.slim, app/views/products/show.html.slim, app/views/reports/show.html.slim, app/views/talks/show.html.slim
各 show アクションで @mentor_memos を取得し、単数パーシャルから複数一覧パーシャルへ差し替え。個別メモ表示と編集 UI のパーシャルを追加・更新。
フロントエンド初期化と UI イベント
app/javascript/initializeMentorMemo.js, app/javascript/mentor-memos.js, app/javascript/importmap_application.js
個別メモ初期化と一覧画面の追加/保存/削除/プレビュー操作を実装し、importmap の参照先を新しいモジュールへ切り替え。
メンターメモ UI のスタイル追加
app/assets/stylesheets/application.css, app/assets/stylesheets/application/blocks/user/_mentor-memos.css
メンターメモ用 CSS を追加し、一覧・メタ情報・アクションの表示を定義。
テスト再構成とフィクスチャ更新
test/system/user/memos_test.rb, test/system/products/mentor_test.rb, test/system/talks/content_test.rb, test/fixtures/users.yml
旧テストを整理し、新しいメモ作成/更新/削除/権限/キャンセル/プレビュー/空状態の検証へ更新。

Sequence Diagram(s)

sequenceDiagram
  actor Mentor as メンター
  participant Browser as ブラウザ
  participant API as API::MentorMemosController
  participant DB as mentor_memos テーブル

  Mentor->>Browser: 追加/編集/削除の操作
  Browser->>API: POST / PUT / DELETE
  API->>API: set_user → set_memo → authorize_memo
  API->>DB: save / update / destroy
  DB-->>API: 結果
  API-->>Browser: HTML / 200 / 204 / 400 / 403
  Browser->>Browser: DOM 更新と表示切替
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • fjordllc/bootcamp#10153: app/javascript/importmap_application.js の import 差し替えが重なっており、同じエントリポイント周辺の変更です。

Suggested reviewers

  • komagata

Poem

🐇 ぴょんと跳ねてメモを追加
くるりと回ってプレビュー確認
だれが書いたか ひと目でわかる
消しても残るよ うさぎの足あと
メンターメモ、ふわっと完成 🌷

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed 作成者と作成時間の追加と1対多化という主変更を簡潔に表しており、内容と整合しています。
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description check ✅ Passed Issue、概要、確認手順、Screenshotが揃っており、テンプレート要件を概ね満たしています。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/add-author-and-timestamp-to-mentor-memos

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

Comment @coderabbitai help to get the list of available commands.

@matuaya matuaya self-assigned this Jun 5, 2026
@matuaya

matuaya commented Jun 5, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 5, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
app/controllers/users_controller.rb (1)

51-51: ⚡ Quick win

メモ取得を権限ユーザーに限定すると漏洩耐性が上がります。

Line 51 は常にメモをロードしているため、ビュー条件が崩れたときに機微情報が露出しやすくなります。取得自体を current_user.admin_or_mentor? で絞るのが安全です。

修正案
-    `@mentor_memos` = `@user.received_memos.includes`(:writer).order(created_at: :desc)
+    `@mentor_memos` =
+      if current_user&.admin_or_mentor?
+        `@user.received_memos.includes`(:writer).order(created_at: :desc)
+      else
+        MentorMemo.none
+      end
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/controllers/users_controller.rb` at line 51, 現在のコード eagerly loads
`@mentor_memos` unconditionally which can expose sensitive memos if view logic
changes; guard the fetch by checking current_user.admin_or_mentor? before
calling `@user.received_memos.includes`(...).order(...), and when the check fails
ensure `@mentor_memos` is set to nil or an empty relation/array so views don't
accidentally display data; locate this in UsersController where `@mentor_memos` is
assigned and wrap or replace that assignment with the conditional using
current_user.admin_or_mentor?.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/controllers/api/mentor_memos_controller.rb`:
- Around line 22-34: The update and destroy actions in MentorMemosController
lack an ownership check allowing other mentors to modify memos; add an
authorization guard that enforces only the memo writer or an admin may perform
updates/deletes. Implement a before_action like authorize_mentor_memo_owner! for
actions :update and :destroy, and implement authorize_mentor_memo_owner! to
return head :forbidden (or raise) unless current_user.id ==
`@mentor_memo.writer_id` || current_user.admin?; apply this to the existing update
and destroy flows so the writer or admin is required.

In `@app/javascript/initializeMentorMemo.js`:
- Around line 65-70: The emptyMessage element can be null (when initial state
has memos), causing a runtime error when calling classList.remove; update the
logic around mentorMemos/emptyMessage in initializeMentorMemo.js to guard before
manipulating DOM: ensure mentorMemos is found, then check emptyMessage is
non-null before calling classList.remove (or use optional chaining), and keep
using memoList.length to determine empty state so the remove is only invoked
when emptyMessage exists.

In `@app/javascript/mentor-memos.js`:
- Around line 61-75: After clearing the editor in the open and cancel handlers,
also reset the save-button state by setting saveButton.disabled = true so an
empty memo cannot be submitted; update the block that clears editorTextarea and
memoEditorPreview (the handler that references toggleClass(modalElements,
'is-hidden'), editorTextarea, memoEditorPreview, and emptyMessage) and the
cancelButton click handler to disable saveButton after clearing the input and
hiding the empty message.

---

Nitpick comments:
In `@app/controllers/users_controller.rb`:
- Line 51: 現在のコード eagerly loads `@mentor_memos` unconditionally which can expose
sensitive memos if view logic changes; guard the fetch by checking
current_user.admin_or_mentor? before calling
`@user.received_memos.includes`(...).order(...), and when the check fails ensure
`@mentor_memos` is set to nil or an empty relation/array so views don't
accidentally display data; locate this in UsersController where `@mentor_memos` is
assigned and wrap or replace that assignment with the conditional using
current_user.admin_or_mentor?.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9843ed5-c590-47d4-9b24-74e93137e473

📥 Commits

Reviewing files that changed from the base of the PR and between 41b116a and 464c372.

📒 Files selected for processing (14)
  • app/controllers/api/mentor_memos_controller.rb
  • app/controllers/users_controller.rb
  • app/javascript/initializeMentorMemo.js
  • app/javascript/mentor-memos.js
  • app/javascript/packs/application.js
  • app/javascript/user_mentor_memo.js
  • app/models/mentor_memo.rb
  • app/models/user.rb
  • app/views/users/_mentor_memo.html.slim
  • app/views/users/_user_mentor_memos.html.slim
  • app/views/users/show.html.slim
  • config/routes/api.rb
  • db/migrate/20260126070916_create_mentor_memos.rb
  • db/schema.rb
💤 Files with no reviewable changes (1)
  • app/javascript/user_mentor_memo.js

Comment thread app/controllers/api/mentor_memos_controller.rb
Comment thread app/javascript/initializeMentorMemo.js
Comment thread app/javascript/mentor-memos.js Outdated
@matuaya

matuaya commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai pause

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews paused.

@matuaya matuaya force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch 3 times, most recently from 91a02c2 to 9fd75b3 Compare June 6, 2026 23:24
@matuaya

matuaya commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@matuaya matuaya force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch from 9fd75b3 to 07f5848 Compare June 7, 2026 23:08
@matuaya

matuaya commented Jun 7, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@matuaya matuaya force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch 3 times, most recently from 1469b5f to 0ee0726 Compare June 9, 2026 21:50
@matuaya

matuaya commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

@machida
機能の実装ができましたのでデザインをご対応していただけると嬉しいです🙇‍♀️
もしなにか修正点などがありましたら教えていただけると助かります🙇‍♀️

@machida machida self-assigned this Jun 16, 2026
@machida machida force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch from 0ee0726 to e00ee87 Compare June 16, 2026 15:04
@machida

machida commented Jun 16, 2026

Copy link
Copy Markdown
Member

@matuaya お待たせしました!!デザイン入れましたー
修正点などはありませんでした👍 バッチリです✨
ちょっとCSSに関する大きめの変更をmainに入れたので、mainからrebaseしました

@machida machida force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch from 5114338 to a0d69da Compare June 17, 2026 06:45
@machida

machida commented Jun 17, 2026

Copy link
Copy Markdown
Member

@matuaya 最新のmainをrebaseしました〜

@matuaya

matuaya commented Jun 17, 2026

Copy link
Copy Markdown
Contributor Author

@machida
デザインを追加してくださりありがとうございます!!
rebaseもしてくださり助かりました🙇‍♀️

@matuaya

matuaya commented Jun 19, 2026

Copy link
Copy Markdown
Contributor Author

@machida
データの移行作業について質問があります🙇‍♀️

これまでの実装ではメモの作成者の情報はなかったのですが、今回の実装で追加したMentorMemo テーブルではメモ作成者のカラムが存在します。
既存のメモを移行する際にwriter: nilにはできないので、こういった場合はどうするのが適切か教えていただけると嬉しいです🙇‍♀️

@machida

machida commented Jun 19, 2026

Copy link
Copy Markdown
Member

@matuaya
質問ありがとうございますー
これは決めの問題になってきますね。駒形さんと相談してみます。

@komagata
過去のメンターメモなのですが、新しいメンターメモには投稿者の情報が必要になるので、今のメモをそのままデータ移行できません。

過去のメンターメモは、

  • 一つのメモとして投稿
  • 投稿者をpjordにする
  • 年月(大体でOK)より以前のメモ、という注意書きを付ける

で、いかがでしょうか?

@komagata

Copy link
Copy Markdown
Member

@machida (CC: @matuaya ) おっしゃるとおりでいいと思います〜

@matuaya matuaya force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch from a0d69da to 1c3507c Compare June 22, 2026 02:46
matuaya and others added 22 commits June 25, 2026 02:00
@matuaya matuaya force-pushed the feature/add-author-and-timestamp-to-mentor-memos branch from 1c3507c to 6a42459 Compare June 24, 2026 17:01
@matuaya matuaya marked this pull request as ready for review June 24, 2026 17:32
@github-actions github-actions Bot requested a review from okuramasafumi June 24, 2026 17:32

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/assets/stylesheets/application/blocks/user/_mentor-memos.css`:
- Around line 25-50: The `.mentor-memo__meta` flex row is too rigid for narrow
screens, causing the writer and `__created-at` metadata to overflow or collide.
Update the styling in `mentor-memos.css` so the meta block can wrap or stack on
small widths, and make `__writer-link`/`__created-at` less restrictive (for
example by allowing wrapping or moving the date to a new line on mobile). Use
the existing `.mentor-memo__meta`, `.mentor-memo__writer-link`, and
`.mentor-memo__created-at` selectors to locate the fix.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5d8f56fd-e018-487a-9a8c-d8dd20e3e7e8

📥 Commits

Reviewing files that changed from the base of the PR and between 07f5848 and 6a42459.

📒 Files selected for processing (8)
  • app/assets/stylesheets/application.css
  • app/assets/stylesheets/application/blocks/user/_mentor-memos.css
  • app/controllers/api/mentor_memos_controller.rb
  • app/controllers/products_controller.rb
  • app/controllers/reports_controller.rb
  • app/controllers/talks_controller.rb
  • app/controllers/users_controller.rb
  • app/javascript/importmap_application.js
✅ Files skipped from review due to trivial changes (3)
  • app/controllers/talks_controller.rb
  • app/controllers/reports_controller.rb
  • app/controllers/users_controller.rb
🚧 Files skipped from review as they are similar to previous changes (2)
  • app/controllers/products_controller.rb
  • app/controllers/api/mentor_memos_controller.rb

Comment on lines +25 to +50
.mentor-memo__meta {
display: flex;
align-items: center;
gap: 0.375rem;
margin-bottom: 0.5rem;
}

.mentor-memo__writer-link {
display: inline-flex;
flex: 0 0 auto;
line-height: 1;
}

.mentor-memo__writer {
font-size: 0.875rem;
line-height: 1.4;
font-weight: 600;
}

.mentor-memo__created-at {
margin-left: auto;
font-size: 0.75rem;
line-height: 1.4;
white-space: nowrap;
color: var(--muted-text);
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

狭い画面でメタ情報が横にはみ出します。

.mentor-memo__meta が1行固定の flex で、__writer-link__created-at もほぼ縮まないため、ユーザー名が長いケースだと日時と衝突してカード幅を超えます。折り返しを許可するか、少なくともモバイルでは日時を次行へ落とせるようにしておいた方が安全です。

💡 修正例
 .mentor-memo__meta {
   display: flex;
   align-items: center;
+  flex-wrap: wrap;
   gap: 0.375rem;
   margin-bottom: 0.5rem;
 }

 .mentor-memo__writer-link {
   display: inline-flex;
-  flex: 0 0 auto;
+  flex: 0 1 auto;
+  min-width: 0;
   line-height: 1;
 }

+@media (width <= 47.9375em) {
+  .mentor-memo__created-at {
+    margin-left: 0;
+  }
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
.mentor-memo__meta {
display: flex;
align-items: center;
gap: 0.375rem;
margin-bottom: 0.5rem;
}
.mentor-memo__writer-link {
display: inline-flex;
flex: 0 0 auto;
line-height: 1;
}
.mentor-memo__writer {
font-size: 0.875rem;
line-height: 1.4;
font-weight: 600;
}
.mentor-memo__created-at {
margin-left: auto;
font-size: 0.75rem;
line-height: 1.4;
white-space: nowrap;
color: var(--muted-text);
}
.mentor-memo__meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 0.375rem;
margin-bottom: 0.5rem;
}
.mentor-memo__writer-link {
display: inline-flex;
flex: 0 1 auto;
min-width: 0;
line-height: 1;
}
.mentor-memo__writer {
font-size: 0.875rem;
line-height: 1.4;
font-weight: 600;
}
.mentor-memo__created-at {
margin-left: auto;
font-size: 0.75rem;
line-height: 1.4;
white-space: nowrap;
color: var(--muted-text);
}
`@media` (width <= 47.9375em) {
.mentor-memo__created-at {
margin-left: 0;
}
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@app/assets/stylesheets/application/blocks/user/_mentor-memos.css` around
lines 25 - 50, The `.mentor-memo__meta` flex row is too rigid for narrow
screens, causing the writer and `__created-at` metadata to overflow or collide.
Update the styling in `mentor-memos.css` so the meta block can wrap or stack on
small widths, and make `__writer-link`/`__created-at` less restrictive (for
example by allowing wrapping or moving the date to a new line on mobile). Use
the existing `.mentor-memo__meta`, `.mentor-memo__writer-link`, and
`.mentor-memo__created-at` selectors to locate the fix.

@komagata komagata assigned komagata and unassigned machida and matuaya Jun 30, 2026
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