Skip to content

ダッシュボードに今が学習予定時間の人を表示する#8711

Merged
komagata merged 16 commits intomainfrom
feature/display_members_scheduled_to_study_now_on_dashboard
Nov 19, 2025
Merged

ダッシュボードに今が学習予定時間の人を表示する#8711
komagata merged 16 commits intomainfrom
feature/display_members_scheduled_to_study_now_on_dashboard

Conversation

@sharoa119
Copy link
Copy Markdown
Contributor

@sharoa119 sharoa119 commented May 30, 2025

Issue

概要

ダッシュボードに(全てのロール、メンターも管理者も研修生もアドバイザーも)、
今が学習予定時間の人のアイコンを表示する。

(例)今が水曜日の10:30だったら、
水曜日の10:00 - 11:00 が学習予定の人全員(現役生、研修生のみ)のアイコンを表示する

変更確認方法

  1. feature/display_members_scheduled_to_study_now_on_dashboardをローカルに取り込む
  2. foreman start -f Procfile.devでローカル環境を立ち上げる
  3. kimuraのアカウントでログイン。パスワードはtesttest
  4. kimura, kensyu, hatsuno を現在の時刻に合わせてrails cでデータを手動追加してから動作確認を行う。
    以下は手順です。
# learning_time_frame_id の計算式
# id = 曜日のインデックス * 24 + 時間 + 1

# 曜日のインデックス:
# 日曜: 0, 月曜: 1, 火曜: 2, 水曜: 3, 木曜: 4, 金曜: 5, 土曜: 6

# 現在の曜日と時刻を元に計算
now = Time.zone.now
day_index = now.wday  # 曜日
hour = now.hour       # 時間(24時間表記)
learning_time_frame_id = day_index * 24 + hour + 1

# ユーザーに学習時間を紐づける
kimura = User.find_by(login_name: 'kimura')
kensyu = User.find_by(login_name: 'kensyu')
hatsuno = User.find_by(login_name: 'hatsuno')

LearningTimeFramesUser.create!(user: kimura, learning_time_frame_id: learning_time_frame_id)
LearningTimeFramesUser.create!(user: kensyu, learning_time_frame_id: learning_time_frame_id)
LearningTimeFramesUser.create!(user: hatsuno, learning_time_frame_id: learning_time_frame_id)
  1. ダッシュボードを リロード し、該当する学習時間に合わせて表示されるユーザーアイコンを確認してください。
  • 表示されるアイコン:kensyu, hatsuno
  • 非表示になるアイコン:ログイン中の kimura(自身のアイコンは表示されない仕様のため)

⚠️ kimuraでログイン中に「kimuraのアイコンが表示されない」のは仕様通りです。

Screenshot

変更前

スクリーンショット 2025-05-27 10 54 10

変更後

スクリーンショット 2025-08-06 17 21 18

Summary by CodeRabbit

  • New Features
    • ダッシュボードに「現在学習中」セクションを追加。同じ時間帯に学習している他のユーザーのアイコンと学習時間帯を表示します。
  • スタイル
    • ダッシュボード用の表示・レスポンシブスタイルを追加し、横スクロールでアイコンを一覧できるようにしました。
  • ヘルパー
    • 表示用の時間帯フォーマット機能を追加しました(日本語の曜日表記、時間範囲表示)。
  • テスト
    • 新しい表示コンポーネントと時間帯フォーマットの自動テストを追加しました。

@sharoa119 sharoa119 force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch from 37819a9 to ce15991 Compare May 30, 2025 08:26
@sharoa119
Copy link
Copy Markdown
Contributor Author

@machida さん
おはようございます!
こちらのアイコンにデザインを入れていただければと思います。
よろしくお願いいたします🙇‍♀️

@sharoa119 sharoa119 force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch from ce15991 to 4288012 Compare June 3, 2025 07:33
@machida
Copy link
Copy Markdown
Member

machida commented Jun 18, 2025

@sharoa119 すいません、こちら見逃してました!!すぐやりますー

貼り付けた画像_2025_06_18_15_04 ↑ 僕をPRのアサインに入れておいてもらえると助かります 🙏

@sharoa119
Copy link
Copy Markdown
Contributor Author

@machida さん
お疲れ様です。
アサインの件、すみませんでした💦
デザイン系は町田さんもアサインに入れる、と覚えておきます。

よろしくお願いいたします🙇‍♀️

@machida
Copy link
Copy Markdown
Member

machida commented Jun 18, 2025

@sharoa119
いえいえ、こちらの方こそ手間かけさせてしまってすいません🙇‍♂️

@machida machida force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch from 1fe1840 to 1e6d91b Compare June 27, 2025 06:02
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jun 27, 2025

Walkthrough

ダッシュボードに「現在学習中」のユーザーアイコン一覧を表示するViewComponentとスタイル、時間範囲ヘルパー、モデルスコープ、コントローラ変数および対応するテストとフィクスチャ修正を追加。

Changes

Cohort / File(s) 変更内容
ViewComponentクラス
app/components/users/current_user_icon_list_component.rb
ViewComponent::Baseを継承する新コンポーネントを追加。TimeRangeHelperをインクルードし、initialize(users:)@usersを受け取る
ViewComponentテンプレート
app/components/users/current_user_icon_list_component.html.slim
.current-user-icon-list構造でタイトル(現在の時間範囲表示)と@usersを反復してユーザーアイコン部分テンプレートをレンダリングするSlimテンプレートを追加
ヘルパーモジュール
app/helpers/time_range_helper.rb
time_range(time)を定義。与えた時刻から「(曜日略) HH:MM 〜 HH:MM」形式の文字列を返すモジュールを追加
ヘルパーテスト
test/helpers/time_range_helper_test.rb
time_rangeの複数ケース(時間切り捨て・00:00越え等)を検証するテストを追加
Controllerロジック
app/controllers/home_controller.rb
display_dashboard@users_for_time_slot = User.currently_learning_except(current_user)を設定する変更を追加
Viewテンプレート(レンダリング)
app/views/home/index.html.slim
@users_for_time_slot.present?の条件でUsers::CurrentUserIconListComponentをレンダリングするブロックを追加
モデルスコープ
app/models/learning_time_frame.rb, app/models/user.rb
LearningTimeFrame.active_nowスコープ(現在の曜日/時間でフィルタ)とUser.currently_learning_except(user)スコープ(active_nowに合致し指定ユーザーを除外、avatar付きのみ)を追加
スタイルシート
app/javascript/stylesheets/application/blocks/dashboard/_current-user-icon-list.sass, app/javascript/stylesheets/application.sass
新しいSassコンポーネントを追加し、application.sassにインポートを挿入。レイアウト・横スクロール・レスポンシブ等を定義
Componentテスト
test/components/users/current_user_icon_list_component_test.rb
複数ユーザーが学習中の場合と現在ユーザーを除外する場合の2ケースでコンポーネント出力を検証するテストを追加
Fixture調整
test/fixtures/learning_time_frames.yml
YAMLのインデント調整(内部ループのブロック位置を移動)。内容は同等

Sequence Diagram(s)

sequenceDiagram
    participant Browser as ブラウザ
    participant Controller as HomeController
    participant Model as User / LearningTimeFrame
    participant View as home/index.html.slim
    participant Component as CurrentUserIconListComponent
    participant Helper as TimeRangeHelper

    Browser->>Controller: GET /home
    Controller->>Model: User.currently_learning_except(current_user)
    activate Model
    Note over Model: LearningTimeFrame.active_nowで<br/>現在の曜日・時間でフィルタ
    Model-->>Controller: `@users_for_time_slot`
    deactivate Model

    Controller-->>View: render with `@users_for_time_slot`
    View->>View: 条件判定 (`@users_for_time_slot.present`?)
    alt ユーザーが存在
        View->>Component: render(users: `@users_for_time_slot`)
        activate Component
        Component->>Helper: time_range(Time.zone.now)
        activate Helper
        Helper-->>Component: "(曜) HH:MM 〜 HH:MM"
        deactivate Helper
        Component->>Component: each `@users` -> render `users/icon` partial
        Component-->>View: HTML断片
        deactivate Component
    else ユーザー無し
        View->>View: コンポーネントをスキップ
    end
    View-->>Browser: HTMLレスポンス
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 注視箇所:
    • LearningTimeFrame.active_now(タイムゾーン、曜日取得、境界時刻処理)
    • User.currently_learning_except(クエリ結合とwith_attached_avatarの組合せ、除外条件)
    • time_rangeの境界ケース(23:00→00:00表示など)
    • テストのFreeze/Time.travelやフィクスチャ参照整合性

Suggested reviewers

  • hirokiej
  • komagata

Poem

🐰🕰️ いまの時間、みんなで学ぶ
小さなアイコンが列をなす
一時間ごとの輪がぽんと咲き
ダッシュボードでひとときの出会い
ぴょんと祝福、うさぎの応援!

Pre-merge checks and finishing touches

❌ 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%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed PR タイトルはダッシュボードに学習予定時間のユーザーアイコンを表示する主な変更を簡潔かつ明確に表現しており、changeset の主要な機能改善を正確に反映しています。
Description check ✅ Passed PR説明はテンプレートの主要セクション(Issue番号、概要、変更確認方法)を完備し、詳細な動作確認手順とスクリーンショットも記載されており、基本的な要件を満たしています。
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/display_members_scheduled_to_study_now_on_dashboard

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b354863 and ec2a137.

📒 Files selected for processing (1)
  • db/schema.rb (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.rb

⚙️ CodeRabbit configuration file

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

Files:

  • db/schema.rb
🧠 Learnings (17)
📓 Common learnings
Learnt from: mousu-a
Repo: fjordllc/bootcamp PR: 8566
File: app/views/application/_global_nav.slim:48-54
Timestamp: 2025-08-28T00:34:28.541Z
Learning: app/views/application/_global_nav.slim のQ&A/ペアワークバッジの環境分岐は、ペアワーク機能の本番リリース後に削除される一時的な実装である。その際、メンター・管理者のみに表示する制限仕様も撤廃される予定のため、現在の実装にはアクセス権限ガードを追加する必要がない。
📚 Learning: 2025-09-08T04:55:46.649Z
Learnt from: sharoa119
Repo: fjordllc/bootcamp PR: 8711
File: db/schema.rb:0-0
Timestamp: 2025-09-08T04:55:46.649Z
Learning: In this PR, the removal of length limits from companies.name and companies.website columns in db/schema.rb was unintentional - it was a case of accidentally lost constraints that needed to be restored to their original limits, not a deliberate design change.

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-04T01:39:22.261Z
Learnt from: Miya096jp
Repo: fjordllc/bootcamp PR: 9102
File: app/controllers/mentor/buzzes_controller.rb:0-0
Timestamp: 2025-09-04T01:39:22.261Z
Learning: fjordllc/bootcamp プロジェクトでは、更新処理の成功時の通知メッセージについて、I18n を使用せずに日本語文字列を直接記述する方針で一貫性を保っている。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-07-23T20:42:19.974Z
Learnt from: jun-kondo
Repo: fjordllc/bootcamp PR: 0
File: :0-0
Timestamp: 2025-07-23T20:42:19.974Z
Learning: fjordllc/bootcampプロジェクトでは、hタグ(見出し)の文言は日本語でハードコーディングする方針が確立されており、I18n対応は行わない。例:app/views/welcome/logo.html.slimでh2、h3タグが日本語でハードコーディングされている。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-06-29T03:44:15.179Z
Learnt from: hirokiej
Repo: fjordllc/bootcamp PR: 8740
File: app/helpers/reports_helper.rb:56-64
Timestamp: 2025-06-29T03:44:15.179Z
Learning: このプロジェクト(fjordllc/bootcamp)では、ja.ymlファイルで一部の単語や文章のみI18n対応されているが、多くのテキストは日本語でハードコーディングされており、完全な国際化対応は行われていない。新しい機能でもI18n対応は不要と判断される。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-07-26T15:24:14.799Z
Learnt from: su-su-su-su
Repo: fjordllc/bootcamp PR: 0
File: :0-0
Timestamp: 2025-07-26T15:24:14.799Z
Learning: fjordllc/bootcampプロジェクトでは、Rubyの述語メソッドには?を付ける命名規則(例: can_be_checker?)を徹底している。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-07-07T05:28:03.676Z
Learnt from: su-su-su-su
Repo: fjordllc/bootcamp PR: 0
File: :0-0
Timestamp: 2025-07-07T05:28:03.676Z
Learning: fjordllc/bootcampプロジェクトでは、fixtureファイル内のERB構文で改行制御文字(-)は使用せず、標準的な<% %>と<%= %>のみを使用する方針が統一されている。<% -%>や<%- %>を使用するとSyntaxErrorが発生する。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-12T21:16:47.639Z
Learnt from: komagata
Repo: fjordllc/bootcamp PR: 9101
File: app/models/graduation_notifier.rb:23-28
Timestamp: 2025-09-12T21:16:47.639Z
Learning: Rails upgrade PRにおいて、configuration systemの変更やwebhook設定の改善提案も、アップグレードに直接関連しない場合は別PRで対応すべきである。PRのスコープ維持が重要。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-04T01:27:23.422Z
Learnt from: Miya096jp
Repo: fjordllc/bootcamp PR: 9102
File: db/fixtures/buzzes.yml:0-0
Timestamp: 2025-09-04T01:27:23.422Z
Learning: The buzz_controller.rb was indeed deleted, but there are still two remaining items from the old buzz single page implementation that need cleanup: the data migration file db/data/20230726024528_create_buzz.rb and the old buzz route in config/routes.rb line 136. These should be updated/removed to complete the buzz page redesign migration.

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-04T01:50:47.773Z
Learnt from: Miya096jp
Repo: fjordllc/bootcamp PR: 9102
File: db/migrate/20250831234516_remove_unique_index_from_buzzes_title.rb:1-5
Timestamp: 2025-09-04T01:50:47.773Z
Learning: fjordllc/bootcampプロジェクトでは、マイグレーションにおいてdisable_ddl_transaction!やalgorithm: :concurrentlyは使用せず、標準的なRailsのchangeメソッド内でremove_indexを実行する慣例がある。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-02T19:01:08.804Z
Learnt from: matuaya
Repo: fjordllc/bootcamp PR: 9108
File: app/models/after_user_retirement.rb:43-45
Timestamp: 2025-09-02T19:01:08.804Z
Learning: fjordllc/bootcampプロジェクトの`app/models/card.rb`は、ActiveRecordモデルではなくStripe APIをラップしたカスタムクラスである。`Card.destroy_all(customer_id)`メソッドは、指定されたcustomer_idに関連付けられたカードのみを削除するカスタム実装で、ActiveRecordの`destroy_all`とは動作が異なり安全である。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-12T21:18:00.834Z
Learnt from: komagata
Repo: fjordllc/bootcamp PR: 9101
File: app/notifiers/discord_notifier.rb:131-135
Timestamp: 2025-09-12T21:18:00.834Z
Learning: Rails アップグレードPRにおいて、product_review_not_completed メソッドの webhook URL 設定の shared フォールバック追加も、設定システム全体の変更として別PRで対応すべきである。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-12T21:17:45.295Z
Learnt from: komagata
Repo: fjordllc/bootcamp PR: 9101
File: app/notifiers/discord_notifier.rb:52-56
Timestamp: 2025-09-12T21:17:45.295Z
Learning: Rails upgrade PRにおいて、configuration systemの改善提案(shared configuration fallback等)も、アップグレードに直接関連しない場合は別PRで対応すべきである。PRのスコープ維持が重要。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-09-11T14:47:53.256Z
Learnt from: komagata
Repo: fjordllc/bootcamp PR: 9101
File: app/models/product.rb:59-61
Timestamp: 2025-09-11T14:47:53.256Z
Learning: Rails アップグレードPRでは、アップグレードに直接関連しない性能改善や機能追加の提案は避けるべき。PRのスコープを維持することが重要で、そのような改善提案は別PRで対応すべきである。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-06-27T14:06:44.472Z
Learnt from: thmz337
Repo: fjordllc/bootcamp PR: 8857
File: db/migrate/20250624141527_remove_experience_from_users.rb:6-8
Timestamp: 2025-06-27T14:06:44.472Z
Learning: Railsのマイグレーションのdownメソッドでは、元のスキーマの正確な定義を確認してから制約を追加する必要がある。元のカラムに制約がない場合、ロールバック時に制約を追加すると元の状態と異なってしまう。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-08-31T03:17:44.812Z
Learnt from: mousu-a
Repo: fjordllc/bootcamp PR: 8566
File: db/migrate/20250830033535_add_default_to_pair_works_wip.rb:1-5
Timestamp: 2025-08-31T03:17:44.812Z
Learning: 新機能のマイグレーションで、まだ本番環境にリリースされていない場合は、既存レコードのバックフィル処理は不要。開発環境でrails db:resetが可能な状況では特に、デフォルト値の変更のみで十分。

Applied to files:

  • db/schema.rb
📚 Learning: 2025-07-15T12:33:04.885Z
Learnt from: reckyy
Repo: fjordllc/bootcamp PR: 8356
File: db/fixtures/users.yml:823-826
Timestamp: 2025-07-15T12:33:04.885Z
Learning: fjordllc/bootcampプロジェクトでは、`trainee: true`は「研修に所属していたユーザー」全体を示すフラグであり、研修中のユーザーと研修を終了したユーザーの両方を含む。そのため、`trainee: true`と`training_completed_at`の併存は意図された仕様であり、排他的な関係ではない。

Applied to files:

  • db/schema.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
🔇 Additional comments (1)
db/schema.rb (1)

980-981: カラム位置変更の確認完了

既存のコメント(行1)での説明通り、sad_streaknegative_streak および last_sad_report_idlast_negative_report_id のリネームを復元し、mainブランチに合わせた変更であることを確認しました。

カラムの制約も正しく維持されています:

  • last_negative_report_id: integer(null許可)
  • negative_streak: boolean(default: false、not null)

テストも通過しているとのことで、問題ありません。

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.81.7)
db/schema.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.81.7/lib/rubocop/config_loader_resolver.rb:310:in rescue in gem_config_path' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader_resolver.rb:293:in gem_config_path'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/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.81.7/lib/rubocop/config_loader_resolver.rb:82:in reverse_each'
/var/lib/gems/3.1.0/g

... [truncated 255 characters] ...

fig_loader_resolver.rb:76:in resolve_inheritance_from_gems' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_loader.rb:58:in load_file'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:34:in options_config=' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/config_store.rb:29:in apply_options!'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:167:in act_on_options' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:49:in block in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:87:in profile_if_needed' /var/lib/gems/3.1.0/gems/rubocop-1.81.7/lib/rubocop/cli.rb:45:in run'
/var/lib/gems/3.1.0/gems/rubocop-1.81.7/exe/rubocop:15:in <top (required)>' /usr/local/bin/rubocop:25:in load'
/usr/local/bin/rubocop:25:in `

'


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 and usage tips.

@machida
Copy link
Copy Markdown
Member

machida commented Jun 27, 2025

@sharoa119 すいません、遅くなりました🙇‍♂️

デザインを入れました!!
その際に修正を加えました。

user_icon_list_component を current_user_icon_list_component という名前に変更して、抽象度を下げました。user_icon_list_component を名乗るには、今回の部分に特化したコンポーネントだったからです。
いずれ、色んなところで(期生別のユーザー一覧、地域別のユーザー一覧など)使えるuser_icon_list_component を作り、差し替えをしたいと思います。これは別Issueにしたいと思います。

user_icon_component を削除し、従来の partial を使うようにしました。
従来の partial を component 化する際、 user_icon_component としたいです。
従来の partial には、画像のaltやtitle設定、ロールの表示などが含まれているので、それらを全て引き継いで user_icon_component にしたいと思います。これも別Issueにしたいと思います。

(曜日)XX:00 〜 XX:00 を表示するためのhelperを作りました。
これは別のコンポーネントでも使う可能性があるので helper で実装しました。
helper をコンポーネントで使うには、コンポーネント内でインポートする必要があるので、current_user_icon_list_componentでインポートしています。

@machida
Copy link
Copy Markdown
Member

machida commented Jun 27, 2025

最新の main を取り込んだので、

手元で、

git pull --rebase origin feature/display_members_scheduled_to_study_now_on_dashboard

をお願いします。

@sharoa119 sharoa119 force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch from 1e6d91b to c01f183 Compare July 11, 2025 05:58
@sharoa119 sharoa119 marked this pull request as ready for review July 11, 2025 06:30
@sharoa119
Copy link
Copy Markdown
Contributor Author

@hirokiej さん
お疲れ様です。
お手隙の際で構いませんので、レビューをお願いできますでしょうか🙇‍♀️

@sharoa119 sharoa119 requested a review from hirokiej July 11, 2025 06:34
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: 4

🧹 Nitpick comments (3)
app/components/users/current_user_icon_list_component.html.slim (2)

9-9: 時刻の取得をViewからコンポーネントクラスに移動することを検討してください

テンプレート内で直接Time.zone.nowを呼び出すのではなく、コンポーネントクラス側で時刻を処理する方が適切です。これにより、テストが容易になり、関心の分離も向上します。

コンポーネントクラスでcurrent_timeを定義し、テンプレートから参照する方法:

-          = time_range(Time.zone.now)
+          = time_range(current_time)

コンポーネントクラス側:

private

def current_time
  Time.zone.now
end

13-17: コメントアウトされたコードの整理を検討してください

UserIconComponentのコメントアウトされた行が残っています。PRコメントによると将来的にコンポーネント化する予定とのことですが、コードベースをクリーンに保つため、不要なコメントアウトコードは削除することを推奨します。

-            //= render UserIconComponent.new(user: user)
test/components/users/current_user_icon_list_component_test.rb (1)

33-36: テスト内のクエリをコントローラーの実装と一致させてください

テスト内で直接クエリを書くのではなく、実際のコントローラーの実装に合わせることで、将来的な変更に対してより堅牢なテストになります。

もしコントローラーでスコープを使用するようにリファクタリングした場合、テストも合わせて更新してください:

-      users_for_time_slot = User.students_and_trainees
-                                .joins(:learning_time_frames)
-                                .merge(LearningTimeFrame.active_now)
-                                .where.not(id: current_user.id)
+      users_for_time_slot = User.currently_learning_except(current_user)
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between eb6fa52 and c01f183.

📒 Files selected for processing (10)
  • app/components/users/current_user_icon_list_component.html.slim (1 hunks)
  • app/components/users/current_user_icon_list_component.rb (1 hunks)
  • app/controllers/home_controller.rb (1 hunks)
  • app/helpers/time_range_helper.rb (1 hunks)
  • app/javascript/stylesheets/application.sass (1 hunks)
  • app/javascript/stylesheets/application/blocks/dashboard/_current-user-icon-list.sass (1 hunks)
  • app/javascript/stylesheets/application/blocks/micro-report/_micro-report.sass (0 hunks)
  • app/models/learning_time_frame.rb (1 hunks)
  • app/views/home/index.html.slim (1 hunks)
  • test/components/users/current_user_icon_list_component_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • app/javascript/stylesheets/application/blocks/micro-report/_micro-report.sass
🧰 Additional context used
📓 Path-based instructions (2)
`**/*.rb`: # refactoring - まずFat Controllerを避け、次にFat Modelを避ける。 - Serviceクラスの乱用を...

**/*.rb: # refactoring

  • まずFat Controllerを避け、次にFat Modelを避ける。
  • Serviceクラスの乱用を避ける。
  • controller concernを作ろうとしたらPORO(Plain Old Ruby Object)やActiveRecordモデルでの実装で代替できないか検討する。

Rails Patterns

  • ViewHelperにメソッドを実装する時にはまずDecoratorパターンを使うことを検討する。(active_decorator gemを導入しているのでそれを使う)
  • 複雑なActiveRecordクエリがあり、再利用できそうな場合はQueryObjectパターンを検討する。(rails-patterns gemを導入しているのでそれのQuery機能を使う)
  • Viewにpartialを作る場合はViewComponentを使うことを検討する。
  • 複数のActiveRecordモデルを操作する1つの責務がある時や外部APIとやりとりする処理がある場合にはInteractorオブジェクトパターンを検討する。(interactor gemを導入しているのでそれを使う)
  • 複数のInteractorを実行するような処理がある場合Organizerオブジェクトパターンを検討する。(interactor gemを導入しており、その中にOrganizerの機能があるので使う)

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • app/controllers/home_controller.rb
  • app/components/users/current_user_icon_list_component.rb
  • app/helpers/time_range_helper.rb
  • test/components/users/current_user_icon_list_component_test.rb
  • app/models/learning_time_frame.rb
`test/**/*`: # Test - TestCase名は英語で書く。 - どうしても避けられない時以外にsystem testでsleepは使わない。 # Unit Test model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

test/**/*: # Test

  • TestCase名は英語で書く。
  • どうしても避けられない時以外にsystem testでsleepは使わない。

Unit Test

model, helper, decorator, view_componentについてはメソッドを追加した場合は必ず対応したUnit TestのTestCaseを1つは書く。

⚙️ Source: CodeRabbit Configuration File

List of files the instruction was applied to:

  • test/components/users/current_user_icon_list_component_test.rb
🧠 Learnings (1)
test/components/users/current_user_icon_list_component_test.rb (1)
Learnt from: kitarou888
PR: fjordllc/bootcamp#8277
File: test/models/searcher_test.rb:326-331
Timestamp: 2025-07-10T12:59:27.746Z
Learning: モデルテストにおいて、1つのクラスメソッドの複数の挙動を検証する場合、機能の異なる側面を同じテストメソッドでテストすることは、包括的なテストとして適切である。特に`only_me`のような機能では、異なる検索条件(空文字と具体的な検索語)を使い分けることで、より広範囲な動作保証が可能となる。
🧬 Code Graph Analysis (2)
app/helpers/time_range_helper.rb (1)
app/models/concerns/watchable.rb (1)
  • time (48-56)
app/models/learning_time_frame.rb (1)
app/javascript/dateFormatter.js (1)
  • weekday (12-12)
🔇 Additional comments (7)
app/models/learning_time_frame.rb (1)

9-24: スコープのロジックは適切です

現在時刻に基づくアクティブな学習時間枠を取得するロジックは正しく実装されています。時間帯とタイムゾーンの処理も適切です。

app/helpers/time_range_helper.rb (1)

4-10: 時間範囲フォーマットの実装は適切です

時間の範囲を適切にフォーマットし、日本語の曜日表示も正しく実装されています。1時間の範囲計算とフォーマットロジックは問題ありません。

app/javascript/stylesheets/application.sass (1)

22-22: CSSインポートの追加は適切です

新しいコンポーネントのスタイルインポートが適切な場所に、既存のパターンに従って追加されています。

app/views/home/index.html.slim (1)

20-21: コンポーネントの条件付きレンダリングは適切です

@users_for_time_slotの存在チェックによる条件付きレンダリングは適切で、空のコンポーネントが表示されることを防いでいます。配置も既存のダッシュボードコンテンツとの整合性が取れています。

app/components/users/current_user_icon_list_component.rb (1)

3-8: ViewComponentの実装は適切です

ViewComponentの実装がRailsのパターンに従っており、TimeRangeHelperのインクルードも適切です。シンプルで焦点を絞った実装になっています。

app/javascript/stylesheets/application/blocks/dashboard/_current-user-icon-list.sass (1)

1-32: SASS構造とレスポンシブデザインは適切に実装されています

コンポーネントのスタイリングは適切に構成されており、以下の点で良好です:

  • BEM風の命名規則に従っている
  • flexboxを使用した適切なレイアウト
  • メディアクエリによるレスポンシブ対応
  • text-blockミックスインを使用した一貫性のあるタイポグラフィ
test/components/users/current_user_icon_list_component_test.rb (1)

8-20: テストケース名を英語で統一してください

コーディングガイドラインに従い、TestCase名は英語で書く必要があります。現在のテスト名は適切ですが、一貫性を保つために確認しました。

Comment on lines +9 to +24
scope :active_now, lambda {
now = Time.zone.now
weekday_map = {
'sunday' => '日',
'monday' => '月',
'tuesday' => '火',
'wednesday' => '水',
'thursday' => '木',
'friday' => '金',
'saturday' => '土'
}
weekday = weekday_map[now.strftime('%A').downcase]
hour = now.hour

where(week_day: weekday, activity_time: hour)
}
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Jul 11, 2025

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

曜日マッピングの重複を解決してください

weekday_mapのロジックがTimeRangeHelperwdays配列と重複しています。一貫性を保つため、共通の定数またはモジュールに抽出することを検討してください。

以下のような共通定数を作成することを提案します:

+  WEEKDAY_MAPPING = {
+    'sunday' => '日',
+    'monday' => '月',
+    'tuesday' => '火',
+    'wednesday' => '水',
+    'thursday' => '木',
+    'friday' => '金',
+    'saturday' => '土'
+  }.freeze
+
   scope :active_now, lambda {
     now = Time.zone.now
-    weekday_map = {
-      'sunday' => '日',
-      'monday' => '月',
-      'tuesday' => '火',
-      'wednesday' => '水',
-      'thursday' => '木',
-      'friday' => '金',
-      'saturday' => '土'
-    }
-    weekday = weekday_map[now.strftime('%A').downcase]
+    weekday = WEEKDAY_MAPPING[now.strftime('%A').downcase]
     hour = now.hour
📝 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
scope :active_now, lambda {
now = Time.zone.now
weekday_map = {
'sunday' => '日',
'monday' => '月',
'tuesday' => '火',
'wednesday' => '水',
'thursday' => '木',
'friday' => '金',
'saturday' => '土'
}
weekday = weekday_map[now.strftime('%A').downcase]
hour = now.hour
where(week_day: weekday, activity_time: hour)
}
WEEKDAY_MAPPING = {
'sunday' => '日',
'monday' => '月',
'tuesday' => '火',
'wednesday'=> '水',
'thursday' => '木',
'friday' => '金',
'saturday' => '土'
}.freeze
scope :active_now, lambda {
now = Time.zone.now
weekday = WEEKDAY_MAPPING[now.strftime('%A').downcase]
hour = now.hour
where(week_day: weekday, activity_time: hour)
}
🤖 Prompt for AI Agents
In app/models/learning_time_frame.rb around lines 9 to 24, the weekday mapping
logic duplicates the wdays array in TimeRangeHelper, causing inconsistency. To
fix this, extract the weekday_map into a shared constant or module that both
LearningTimeFrame and TimeRangeHelper can use. Replace the inline weekday_map in
this scope with a reference to that shared constant to maintain consistency and
avoid duplication.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

共通定数を作成する。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧩 Analysis chain

@sharoa119 承知いたしました。共通定数を作成して曜日マッピングの重複を解決いたします。

Task: Create shared weekday mapping constant

  • First examine TimeRangeHelper implementation to understand current duplication
  • Create shared constant for weekday mapping
  • Update LearningTimeFrame to use shared constant
  • Update TimeRangeHelper to use shared constant

🏁 Script executed:

# Check the current implementation of TimeRangeHelper
cat app/helpers/time_range_helper.rb

Length of output: 328


@sharoa119 TimeRangeHelperの実装を確認しました。現在の重複を解決するための共通定数を作成いたします。

Task: Create shared weekday mapping constant

  • Create shared module with both array and hash formats for weekday mapping
  • Update LearningTimeFrame to use shared constant
  • Update TimeRangeHelper to use shared constant

🧬 Code Graph Analysis Results

Possibly relevant snippets from app/javascript/dateFormatter.js (line 12)

const weekday = dateObj.toLocaleDateString('ja-JP', { weekday: 'short' })

This snippet shows a way to get the weekday in Japanese short format from a JavaScript Date object, which relates to the weekday mapping in LearningTimeFrame model.


No other relevant code snippets found related to defining or centralizing common constants for weekdays or activity times.


⏳ Preparing changes...

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

A summary of the changes CodeRabbit can apply:

  • Refactor multiple Ruby files to centralize Japanese weekday mappings by creating a shared WeekdayMapping module in app/lib and updating all references to use this module’s constants, thereby eliminating duplicate weekday arrays and hashes across the codebase.

  • Refactor the codebase by extracting weekday-to-Japanese mappings into a new shared module WeekdayMapping in app/lib/weekday_mapping.rb, then update LearningTimeFrame and TimeRangeHelper to include this module and replace their inline weekday mappings with references to the shared constants for improved code reuse and maintainability.

  • Refactor the codebase by creating a shared WeekdayMapping module with Japanese weekday constants, then update LearningTimeFrame and TimeRangeHelper files to use this module instead of duplicating weekday mappings, improving maintainability and consistency.

  • ✅ Create PR with these edits
  • 📌 Create commit in current branch
  • 📋 Get copyable edits

@hirokiej
Copy link
Copy Markdown
Contributor

返信が遅くなってしまいすみません💦
現在、別のレビューを受け持っており、そちらがまだ一切手をつけられていない状態で、それが終わり次第なので、だいぶ時間がかかってしまうかもしれません。
2−3週間いただけたら幸いです。
それでも大丈夫でしたら、レビューさせてください🙇💦

@sharoa119
Copy link
Copy Markdown
Contributor Author

@hirokiej さん
お疲れ様です。
はい、急ぎではないのでお時間ある時で構いません!
よろしくお願いいたします🙇‍♀️

@komagata
Copy link
Copy Markdown
Member

@sharoa119 生徒の方にレビュー依頼する前に coderabbit の指摘点に対応してみてください〜

@sharoa119 sharoa119 force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch from c01f183 to 3838d1b Compare July 14, 2025 12:37
@hirokiej
Copy link
Copy Markdown
Contributor

komagataさんがご指摘くださった点に加えて、一部のコミットメッセージが主観的であったり、変更履歴として他の方が意図を把握しづらい可能性があるように見受けられました。
こちらも整理していただけると助かります🙏

以下の記事が参考になると思いますので、よければご確認いただけたらと思います🙇

また、私の方でも同様の内容で記事を執筆しているので、よければこちらもご覧ください🙇

@sharoa119
Copy link
Copy Markdown
Contributor Author

@hirokiej さん
お疲れ様です。
返答が遅くなってすみません。メンションがなかったからかコメントされても通知がなく、今コメントに気づきました💦

コミットへのご指摘、ありがとうございます!
昔、コミットをしなさすぎて注意されたことがあったので、ちょこちょこコミットをするようにしていたのですが、それが逆にまとまっていない状態になっていましたね。すみませんでした。

整理できそうな箇所はまとめてみたいと思います。しばしお待ちください🙇‍♀️

@hirokiej
Copy link
Copy Markdown
Contributor

@sharoa119 さん
すみません💦メンションがなくても通知がいくものだと思っていました🙏

コミットへのご指摘、ありがとうございます!
昔、コミットをしなさすぎて注意されたことがあったので、ちょこちょこコミットをするようにしていたのですが、それが逆にまとまっていない状態になっていましたね。すみませんでした。

いえ、全然大丈夫ですー!
もしかしたら、以下の記事も参考になるかもなので、そちらも参照いただけたらと思います🙇
コードより先にコミットメッセージを書く - tebiki_techblog

あと、コミットしなさすぎの件について、すでにご存知かもしれませんが、git add -pで解決できるのかなと思いました。
こちらも私の記事で恐縮なのですが、参考になれば幸いです🙇
初めての人のためのgit add -pの使い方 - IT's not Rocket Science!

@sharoa119 sharoa119 force-pushed the feature/display_members_scheduled_to_study_now_on_dashboard branch 6 times, most recently from d11e79c to 35955c3 Compare July 30, 2025 09:24
This was referenced Dec 19, 2025
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.

7 participants