Skip to content

給付金コースのプラクティスの関連Docs一覧に、元コースの関連日報できるようにする。#9650

Open
kutimiti1234 wants to merge 13 commits intomainfrom
feature/docs-grant-course-filter
Open

給付金コースのプラクティスの関連Docs一覧に、元コースの関連日報できるようにする。#9650
kutimiti1234 wants to merge 13 commits intomainfrom
feature/docs-grant-course-filter

Conversation

@kutimiti1234
Copy link
Contributor

@kutimiti1234 kutimiti1234 commented Feb 14, 2026

Issue

概要

変更確認方法

1.feature/docs-grant-course-filterをローカルに取り込む
2. http://localhost:3000/practices/200789251/pages へ遷移
3. ピル型タブで「全て」が表示されていることを確認
4. デフォルトで給付金コースと元コース(http://localhost:3000/practices/315059988) のどちらのDocsも表示されていることを確認する。
5. ピル型タブで「給付金コース」をクリック
6. http://localhost:3000/practices/200789251/pages?target=only_grant_courseに遷移していることを確認
7. 給付金コースのDocsだけが表示されていることを確認。

Screenshot

変更前

image

変更後

Summary by CodeRabbit

  • 新機能

    • 給付金コース向けのドキュメント絞り込みUIを追加(「全て」「給付金コース」)。該当時のみ表示。
  • 改善

    • ページ一覧でコピー元のドキュメントを併合して表示できるようにし、絞り込み後に一括で並び替え・ページングを適用。
    • Docsタブの件数表示を給付金コース判定に応じて集計するよう変更。
  • テスト

    • フィルター表示・動作を検証するシステム/モデルテストを追加。
  • 雑多

    • 表示や検証に使うデータセット(fixtures)を追加。

@coderabbitai
Copy link

coderabbitai bot commented Feb 14, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

給付金コース(source_id を持つ実践)でページ取得を @practice.pages 経由に切替し、必要に応じて source_practice.pages を union で結合するコントローラ変更、UI フィルタ、モデルヘルパー、フィクスチャとテストを追加しました。

Changes

Cohort / File(s) Summary
Controller
app/controllers/practices/pages_controller.rb
ページ取得を @practice.pages ベースに変更。@practice.grant_course? かつ params[:target] != 'only_grant_course' の場合は source_practice.pages を union で結合。includes・order・pagination を結合後に適用。
Model
app/models/practice.rb
grant_course?own_and_source_practice_pages_length のインスタンスメソッドを追加。
Helper
app/helpers/page_tabs/practices_helper.rb
Docs タブの件数を grant_course? 時に own_and_source_practice_pages_length に切替。
Views
app/views/practices/pages/index.html.slim, app/views/practices/_grant_course_filter.html.slim
給付金コース用フィルタ部分テンプレートを追加し、grant_course? 時に「全て/給付金コース」切替を表示。
Fixtures — db/
db/fixtures/users.yml, db/fixtures/discord_profiles.yml, db/fixtures/talks.yml, db/fixtures/practices.yml, db/fixtures/categories.yml, db/fixtures/categories_practices.yml, db/fixtures/courses_categories.yml, db/fixtures/pages.yml, db/fixtures/reports.yml
給付金コース用ユーザー・プロフィール・トーク・実践・カテゴリ・ページ・日報等のデータを追加・更新。
Test fixtures & Tests
test/fixtures/practices.yml, test/fixtures/pages.yml, test/models/practice_test.rb, test/system/practice/pages_test.rb
source/copy 実践とページのテストフィクスチャ追加。grant_course?own_and_source_practice_pages_length の単体テスト及びフィルタ表示・動作のシステムテストを追加。

Sequence Diagram(s)

sequenceDiagram
    participant User as ブラウザ(User)
    participant App as Rails App(PagesController)
    participant DB as Database
    participant Src as SourcePractice

    User->>App: GET /practices/:id/pages?target=...
    App->>DB: load Practice(id)
    App->>DB: load practice.pages (includes comments, avatar)
    alt practice.grant_course? && params.target != 'only_grant_course'
        App->>DB: load source_practice.pages (includes comments, avatar)
        App->>App: union practice.pages + source_practice.pages
    end
    App->>App: apply order, pagination (.order/.page/.per)
    App->>User: render pages/index (grant_course filter shown if applicable)
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested reviewers

  • komagata

Poem

🐰 給付金コースの草原でぴょん、
ソースのページもいっしょにぴょん、
「全て」か「コース」かぽんと選べば、
ドキュメントがふわっと広がるぴょん、
みんなで跳ねるリリースおめでとう! 🎉

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed タイトルはプルリクエストの主な変更内容(給付金コースのDocsフィルタリング機能)を明確に説明しており、変更セット全体の要点を適切に要約しています。
Description check ✅ Passed プルリクエストの説明は Issue リンク、概要、変更確認方法を含み、リポジトリテンプレートの主要セクションをカバーしています。ただし、スクリーンショットの「変更後」が不足しており、説明が不完全です。

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/docs-grant-course-filter

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

@kutimiti1234
Copy link
Contributor Author

給付金コースの「全て」に給付金コースのDocsが表示されていない致命的なバグがあったため修正しました。

@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch 14 times, most recently from 22740f8 to ce8dbe8 Compare February 18, 2026 11:59
@kutimiti1234 kutimiti1234 changed the title 給付金コースのプラクティスの関連Docs一覧に元コースの関連日報を表示切替のフィルターを追加 給付金コースのプラクティスの関連Docs一覧に、元コースの関連日報できるようにする。 Feb 21, 2026
@kutimiti1234
Copy link
Contributor Author

kutimiti1234 commented Feb 24, 2026

@komagata
こちらのPRで1点相談させていただきたいです。
現状、このPRで、test\models\practice_progress_migrator_test.rbのテストで下記のようなエラーが発生しています。
image

image

こちら原因としては、test/fixtures/practices.ymlに下記のfixtureを追加したことが原因です。(develop環境と同じようなデータ)

practice64:
  title: "OS X Mountain Lionをクリーンインストールする(Reスキル)"
  description: "Railsコースのプラクティスをコピーしたプラクティスです。"
  source_id: <%= ActiveRecord::FixtureSet.identify(:practice1) %>

practice65:
  title: "Terminalの基礎を覚える(Reスキル)"
  description: "Railsコースのプラクティスをコピーしたプラクティスです。"
  source_id: <%= ActiveRecord::FixtureSet.identify(:practice2) %>

具体的にはapp/models/practice_progress_migrator.rbの中で、10行目と42行目にそれぞれ

    copied_practice = Practice.find_by(source_id: practice_id)
    copied_practice = Practice.find_by(source_id: practice.id)

と書かれていたため、test/models/practice_progress_migrator_test.rbの中でコピーされたプラクティスではなく、fixtureで設定されたプラクティスが取得されていたことが原因でした。

ただし、PracticeProgressMigratorの実装はそもそも給付金コースのプラクティスが元のコースから1個だけしかコピーしない前提でつくられていると思うので、間違ってはいないと思います。

そこで、こういった場合にどういった対処法がよいか相談させていただきたいです。
一旦下記2通りを考えています。

1, app/models/practice_progress_migrator.rbで下のような変更を行う

-    copied_practice = Practice.find_by(source_id: practice_id)
+    copied_practice = Practice.where(source_id: practice_id).order(:created_at).last
-      copied_practice = Practice.find_by(source_id: practice.id)
+      copied_practice = Practice.where(source_id: practice.id).order(:created_at).last

メリット:fixtureを変更する必要がない。
デメリット:本来起こりえない1つのプラクティス対して2つ以上のコピーしたプラクティスがつくられるかもしれないという実装を作ることになる。

  1. fixtureのsource_idのプラクティスを別のプラクティスに変更する。

メリット:今回のスコープ外である app/models/practice_progress_migrator.rbの実装を変える必要がない
デメリット:develop環境と同じテストデータでテストできない。

個人的には2かなと思っているのですが、念のため相談させていただきたいです。

@kutimiti1234
Copy link
Contributor Author

  1. test\models\practice_progress_migrator_test.rbのsetupでpractice64,65をdestroyする。
    メリット:実装側を変える必要も、fixture側を変える必要もないので素直な実装な気がする
    デメリット:その場しのぎの手法であり、かつ、一見してdestroyの必要性がわからない。

3個目の案を追加しました。改めて考えるとこの3が一番素直に感じており、良いのかなと考えています

@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch 2 times, most recently from 1274c71 to deb4d1c Compare February 25, 2026 11:35
@torinoko
Copy link
Contributor

@kutimiti1234
通りすがりの文鳥が新たなものを提案します!

  1. コピー元に使うための fixture を用意する

がよいんじゃないかな〜と思いました!
原因は practice64, practice65 で practice1, practice2 を使用していることなんですよね。
なのでコピー元用の fixture を用意し、コピー先でそちらを参照するのがきれいかな〜って。
それぞれの fixture も連番ではなく、用途がわかるラベルをつけるといいかなって。
あと Practice モデルには source_id をキーにして source_practice へのアソシエーションが張られているので、fixture にもこれを活用するとすっきり表現できるんじゃないかなって。

source_practice1:
  title: "コピー元のプラクティス1"
  description: "description..."
  goal: "goal..."
  memo: "memo for mentors..."

source_practice2:
  title: "コピー元のプラクティス2"
  description: "description..."
  goal: "goal..."
  memo: "memo for mentors..."

copy_practice1:
  title: "コピー先のプラクティス1"
  description: "copy1..."
  source_practice: source_practice1

copy_practice2:
  title: "コピー先のプラクティス2"
  description: "copy2..."
  source_practice: source_practice2

蛇足ですが

こちらのPRで1点相談させていただきたいです。 現状、このPRで、test/models/practice_progress_migrator_test.rbのテストで下記のようなエラーが発生しています。

こういうときは画面キャプチャよりテキストをぺろっと貼っていただいた方が個人的には嬉しいかな!と思いました(これは本当に個人の感想です)

@torinoko
Copy link
Contributor

practices(:practice64).destroy
practices(:practice65).destroy

これは @kutimiti1234 が書いているとおり、「destroy の必要性がわからない」ので避けたい気持ちがあります。
practice_progress_migrator のテストには関係ないことですしね。
後でコードを見た人が「何でこれだけ destroy してるの?」って不思議に思っちゃいそう。
で、commit や PR で経緯を追ってようやく「なるほど!」ってなる。
それは無駄な時間になっちゃうんじゃないかな〜。

なので事情をコメントに書いておくという方法もあるけど、それでも「いや事情はわかったけどここだけ destory するってやっぱり不思議だな?」ってなってしまう気がします。
できるだけ読み手を悩ませない実装はきっとあるはず……!

@komagata
Copy link
Member

@kutimiti1234

@torinoko さんの案が良いと思います。

既存のテストは絶対変更しちゃいけないってことはないですが、この件では変更する必要もないかなとおもうので。

@kutimiti1234
Copy link
Contributor Author

@torinoko @komagata
ご提案&検討ありがとうございます。
Fixtureへの@torinokoさんの案のものを追加する方針で進めたいと思います。

@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch 2 times, most recently from c4e00f8 to 16ab24b Compare February 26, 2026 13:22
@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch from 16ab24b to 241f3b2 Compare February 27, 2026 09:39
@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch from 241f3b2 to 1a264bf Compare February 27, 2026 09:40
@kutimiti1234 kutimiti1234 marked this pull request as ready for review February 27, 2026 09:47
@github-actions github-actions bot requested a review from komagata February 27, 2026 09:47
Copy link

@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: 6

🧹 Nitpick comments (1)
app/controllers/practices/pages_controller.rb (1)

9-15: includesの重複を削除できます。

10行目でincludesを適用済みのため、13-14行目のincludesは冗長です。.or()で結合された結果にも最初のincludesが適用されます。

♻️ 提案する修正
     `@pages` = `@practice.pages`
-                      .includes(:comments, :practice, { last_updated_user: { avatar_attachment: :blob } })

     if `@practice.grant_course`? && params[:target] != 'only_grant_course'
-      `@pages` = `@pages.or`(`@practice.source_practice.pages`).includes(:comments, :practice,
-                                                                   { last_updated_user: { avatar_attachment: :blob } })
+      `@pages` = `@pages.or`(`@practice.source_practice.pages`)
     end

-    `@pages` = `@pages.order`(updated_at: :desc, id: :desc)
+    `@pages` = `@pages.includes`(:comments, :practice, { last_updated_user: { avatar_attachment: :blob } })
+                   .order(updated_at: :desc, id: :desc)
                    .page(params[:page])
                    .per(PAGER_NUMBER)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/practices/pages_controller.rb` around lines 9 - 15, `@pages` is
initialized with `@practice.pages.includes`(...), so remove the redundant
.includes(...) chained onto the .or(`@practice.source_practice.pages`) branch;
keep the initial .includes on the `@pages` assignment and change the conditional
branch to simply do `@pages` = `@pages.or`(`@practice.source_practice.pages`) so the
original includes apply to the combined relation (refer to `@pages`,
`@practice.pages`, .includes and .or(...)).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@app/controllers/practices/pages_controller.rb`:
- Around line 12-15: Change the direct call to `@practice.source_practice.pages`
to a nil-safe call to avoid potential NoMethodError: replace
`@practice.source_practice.pages` with `@practice.source_practice`&.pages in the
conditional block (the code that assigns `@pages` using
`@practice.source_practice.pages`) so it mirrors the nil-safe pattern used in
own_and_source_practice_pages_length in Practice model and keeps the
includes(:comments, :practice, { last_updated_user: { avatar_attachment: :blob }
}) intact.

In `@app/models/practice.rb`:
- Around line 214-216: own_and_source_practice_pages_length calls
source_practice.pages without guarding for source_practice being nil, causing
NoMethodError; update the method (own_and_source_practice_pages_length) to
handle nil by treating missing source_practice as zero pages (e.g. use safe
navigation or a conditional to use 0 when source_practice is nil) and keep
summing with pages.length.

In `@db/fixtures/categories.yml`:
- Around line 117-119: The fixture entry for category24 has a mismatched name
and slug: name is "Mac OS X(Reスキル)" but slug is "ready-for-learn"; update the
slug to reflect the category name (e.g., "mac-os-x-re-skill" or
"mac-osx-re-skill") so the slug semantically matches the name; locate the
category fixture entry labeled category24 in categories.yml and replace the slug
"ready-for-learn" with the corrected slug.

In `@db/fixtures/practices.yml`:
- Around line 768-776: The fixtures practice113 and practice114 are missing the
required Practice attribute "goal"; update the practice113 and practice114
entries to include a goal key (e.g., a short string or copy the goal from the
referenced source practice1/practice2) so the fixtures satisfy Practice
validations (look for the practice113 and practice114 entries and add a goal:
"<appropriate goal text>" field).

In `@test/system/practice/pages_test.rb`:
- Around line 45-51: The test name string in the test case (the one starting
with test 'grant filter shows only grant course reports when "給付金コース" is
selected' do) is misleading because the body asserts Docs page behavior; change
"reports" to "docs" in that test description so the test name accurately
reflects what the test verifies (referencing the test block starting with test
'...').
- Around line 53-59: Rename the test's description string to match what's being
tested: update the test named "grant filter shows empty message when no reports
exist" to something like "grant filter shows empty message when no docs exist"
(or "when no pages exist") so it reflects that the test visits Pages
(visit_with_auth "/practices/#{practices(:copy_practice2).id}/pages") and
asserts the Docs empty message; change the string in the test definition only
(the test ... do line) to keep assertions and behavior in methods like
visit_with_auth and find unchanged.

---

Nitpick comments:
In `@app/controllers/practices/pages_controller.rb`:
- Around line 9-15: `@pages` is initialized with `@practice.pages.includes`(...), so
remove the redundant .includes(...) chained onto the
.or(`@practice.source_practice.pages`) branch; keep the initial .includes on the
`@pages` assignment and change the conditional branch to simply do `@pages` =
`@pages.or`(`@practice.source_practice.pages`) so the original includes apply to the
combined relation (refer to `@pages`, `@practice.pages`, .includes and .or(...)).

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0001ea9 and 1a264bf.

📒 Files selected for processing (18)
  • app/controllers/practices/pages_controller.rb
  • app/helpers/page_tabs/practices_helper.rb
  • app/models/practice.rb
  • app/views/practices/_grant_course_filter.html.slim
  • app/views/practices/pages/index.html.slim
  • db/fixtures/categories.yml
  • db/fixtures/categories_practices.yml
  • db/fixtures/courses_categories.yml
  • db/fixtures/discord_profiles.yml
  • db/fixtures/pages.yml
  • db/fixtures/practices.yml
  • db/fixtures/reports.yml
  • db/fixtures/talks.yml
  • db/fixtures/users.yml
  • test/fixtures/pages.yml
  • test/fixtures/practices.yml
  • test/models/practice_test.rb
  • test/system/practice/pages_test.rb

Copy link

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/system/practice/pages_test.rb`:
- Around line 53-60: Rename the test description string for the test that
currently begins with "grant filter shows only grant course pages when
\"給付金コース\" is selected but source practice has no practices" to accurately
reflect that the setup destroys pages (i.e., change "has no practices" to "has
no pages"); update the test declaration (the test '...') so the human-readable
name matches the action performed on
practices(:source_practice1).pages.destroy_all and run the test suite to
confirm.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4c17afa and 9188629.

📒 Files selected for processing (2)
  • app/controllers/practices/pages_controller.rb
  • test/system/practice/pages_test.rb

Copy link

@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.

♻️ Duplicate comments (2)
app/models/practice.rb (1)

214-216: ⚠️ Potential issue | 🟠 Major

source_practice が nil のケースで落ちる可能性があります。

Line 215 は source_practice を直接参照しているため、関連が欠けたデータで NoMethodError になります。件数取得は length より size が適しています。

💡 修正案
 def own_and_source_practice_pages_length
-  pages.length + source_practice.pages.length
+  pages.size + source_practice&.pages&.size.to_i
 end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/models/practice.rb` around lines 214 - 216,
own_and_source_practice_pages_length currently calls
source_practice.pages.length which raises NoMethodError when source_practice is
nil and uses length instead of size; update the method
(own_and_source_practice_pages_length) to defensively handle a nil
source_practice (e.g., treat missing source_practice as zero pages) and use size
on both collections (pages.size and source_practice&.pages&.size || 0) so it
returns a correct integer even when source_practice is absent.
app/controllers/practices/pages_controller.rb (1)

13-15: ⚠️ Potential issue | 🟠 Major

条件式で source_practice の nil ガードが不足しています。

Line 13 の source_practice.pages.present? は、source_practice が nil の場合に例外になります。

💡 修正案
-    if `@practice.grant_course`? && params[:target] != 'only_grant_course' && source_practice.pages.present?
+    if `@practice.grant_course`? && params[:target] != 'only_grant_course' && source_practice && source_practice.pages.present?
       `@pages` = `@pages.or`(source_practice.pages).includes(:comments, :practice,
                                                          { last_updated_user: { avatar_attachment: :blob } })
     end
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@app/controllers/practices/pages_controller.rb` around lines 13 - 15, The
condition uses source_practice.pages.present? without guarding for
source_practice being nil; update the conditional to check source_practice first
(for example change source_practice.pages.present? to source_practice.present?
&& source_practice.pages.present? or use safe navigation
source_practice&.pages.present?) so the `@pages` =
`@pages.or`(source_practice.pages).includes(...) assignment only runs when
source_practice exists and has pages.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@app/controllers/practices/pages_controller.rb`:
- Around line 13-15: The condition uses source_practice.pages.present? without
guarding for source_practice being nil; update the conditional to check
source_practice first (for example change source_practice.pages.present? to
source_practice.present? && source_practice.pages.present? or use safe
navigation source_practice&.pages.present?) so the `@pages` =
`@pages.or`(source_practice.pages).includes(...) assignment only runs when
source_practice exists and has pages.

In `@app/models/practice.rb`:
- Around line 214-216: own_and_source_practice_pages_length currently calls
source_practice.pages.length which raises NoMethodError when source_practice is
nil and uses length instead of size; update the method
(own_and_source_practice_pages_length) to defensively handle a nil
source_practice (e.g., treat missing source_practice as zero pages) and use size
on both collections (pages.size and source_practice&.pages&.size || 0) so it
returns a correct integer even when source_practice is absent.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9188629 and 9f7e154.

📒 Files selected for processing (2)
  • app/controllers/practices/pages_controller.rb
  • app/models/practice.rb

@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch from 9f7e154 to 88f5d05 Compare February 27, 2026 23:05
Copy link

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@test/system/practice/pages_test.rb`:
- Line 54: The test is failing due to a fixture key typo: replace the
non-existent practices(:eopy_practice3) used in visit_with_auth with the correct
fixture key practices(:copy_practice3); update the call in
test/system/practice/pages_test.rb (the visit_with_auth line) so it references
practices(:copy_practice3) and rerun the test to confirm the fix.

ℹ️ Review info

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9f7e154 and 88f5d05.

📒 Files selected for processing (6)
  • app/controllers/practices/pages_controller.rb
  • app/models/practice.rb
  • test/fixtures/pages.yml
  • test/fixtures/practices.yml
  • test/models/practice_test.rb
  • test/system/practice/pages_test.rb
🚧 Files skipped from review as they are similar to previous changes (3)
  • app/models/practice.rb
  • app/controllers/practices/pages_controller.rb
  • test/fixtures/pages.yml

@kutimiti1234 kutimiti1234 force-pushed the feature/docs-grant-course-filter branch from 88f5d05 to a08c0fc Compare February 27, 2026 23:13
@kutimiti1234 kutimiti1234 requested a review from machida February 28, 2026 13:26
@kutimiti1234
Copy link
Contributor Author

@machida
お疲れ様です。
こちらapp/views/practices/_grant_course_filter.html.slimへデザインいただけますでしょうか?

@machida machida force-pushed the feature/docs-grant-course-filter branch from 8baecb7 to 27f653a Compare March 3, 2026 15:55
@machida
Copy link
Member

machida commented Mar 3, 2026

@kutimiti1234 お待たせしました!!レイアウト修正をしましたー

@kutimiti1234
Copy link
Contributor Author

@machida
迅速なご対応ありがとうございました!

Copy link
Contributor

@torinoko torinoko left a comment

Choose a reason for hiding this comment

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

@kutimiti1234
またシュッと失礼します!

source_practice = @practice.source_practice

@pages = @practice.pages
.includes(:comments, :practice, { last_updated_user: { avatar_attachment: :blob } })
Copy link
Contributor

@torinoko torinoko Mar 4, 2026

Choose a reason for hiding this comment

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

また余計なツッコミをしてしまうのだけど、できれば includes を使用する際は以下のような仕様であることを認識した上で使用指定ただけると嬉しいです。

  • 条件に応じて発行される SQL が変わる
  • このため、意図しない SQL が発行される可能性がある

これに関してはこちらの記事がわかりやすいかな?
https://tech.smarthr.jp/entry/2025/06/03/113908

あとこういうこともあったりします。
組み立てたリレーションを再利用するときなどに無駄なコストが発生してしまう可能性もあるんですね。

知っておくと良い注意点は、リレーションオブジェクトにincludesがあると、eager loadingが不必要なクエリにおいてでも、pluckがeager loadingを引き起こすことです。以下に例を示します。
https://railsguides.jp/active_record_querying.html#pluck

ほとんどの場合、N + 1 が発生するよりは遥かによい結果になるかもしれません。だけど書き手の意図しない SQL の発行はリスクをはらみます。
なので #includes のご利用は計画的に!

@pages = @practice.pages
.includes(:comments, :practice, { last_updated_user: { avatar_attachment: :blob } })

if @practice.grant_course? && params[:target] != 'only_grant_course' && source_practice.pages.present?
Copy link
Contributor

Choose a reason for hiding this comment

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

条件式が複雑になる場合は、この式をまるっと private メソッドに切り出すという手段もあります。

  • プラクティスが grant_course を持っている
  • params[:target] が only_grant_course ではない
  • source_practice がページを持っている
def has_source_course?
  @practice.grant_course? &&
     params[:target] != 'only_grant_course' &&
     @practice.source_practice.pages.present?
end

あと #grant_course? 自体が source_id の有無を確認しているだけなので、メソッド化するメリットってあるのかな?とちょっと思いました。

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.

5 participants