Skip to content

タグ機能を非React化#8881

Merged
komagata merged 16 commits intomainfrom
chore/replace-tags-implementation
Jul 24, 2025
Merged

タグ機能を非React化#8881
komagata merged 16 commits intomainfrom
chore/replace-tags-implementation

Conversation

@e-yanagita-gs
Copy link
Copy Markdown
Contributor

@e-yanagita-gs e-yanagita-gs commented Jul 3, 2025

Issue

概要

これまでReactで実装されていたタグの表示・編集コンポーネント(Tags.jsx)を、Railsのview + 少しのVanilla JS(Tagifyライブラリ)の組み合わせに置き換えるリファクタリングを行いました。

これにより、特定のページにおけるReactへの依存をなくし、技術スタックの統一を図ります。今回は、UserMovieなど、複数のモデルで汎用的に利用されているタグ部品を対象としました。

  • タグの表示・編集機能
  • 編集内容の保存・キャンセル機能
  • バリデーション、オートコンプリートなどの補助機能

変更確認方法

  1. chore/replace-tags-implementation ブランチをローカルに取り込みます。

    git fetch origin chore/replace-tags-implementation
    git checkout chore/replace-tags-implementation
  2. foreman start -f Procfile.devでサーバーを立ち上げます。


1. 基本的な表示と編集モードへの切り替え確認

  1. 任意の編集権限を持つユーザー(例: kimura)でログインし、自身のプロフィールページ(例: /users/kimura)にアクセス。

    • ページ読み込み時、設定されているタグが正しくリンク付きで表示されていることを確認。
    • 各タグのリンク先が正しいこと(例: /users/tags/(タグ名))も確認。
    • 「タグ編集」リンクが表示されていることを確認。
  2. 「タグ編集」リンクをクリック。

    • 表示モードが非表示になり、編集フォームが表示されることを確認。
    • 編集フォーム内の入力欄に、現在のタグが正しく設定されていることも確認。

2. タグの編集・保存・キャンセル機能の確認

  1. 上記の手順で編集モードに切り替えた後、新しいタグ(例: テスト)を入力して追加し、「キャンセル」ボタンをクリック。

    • ビューが編集前の状態に戻り、追加しようとした「テスト」タグが表示されていないことを確認。
  2. 再度「タグ編集」をクリックし、新しいタグ(例: テスト)を追加し、既存のタグを一つ削除してから「保存する」ボタンをクリック。

    • ビューが更新された状態(新しいタグが追加され、古いタグが削除されている)で表示モードに戻ることを確認。
  3. ページを再読み込み。

    • 保存した内容が維持されていることを確認。

3. バリデーションと入力補助機能の確認

  1. 編集モードに切り替える。
  2. タグ入力欄にhello worldのようにスペースを含む文字を入力し、Enterキーを押す。
    • アラート等でエラーメッセージが表示され、タグが追加されないことを確認。
  3. タグ入力欄に#Rubyのように**#を先頭につけた文字**を入力し、Enterキーを押す。
    • 先頭の#が自動で除去され、Rubyというタグだけが追加されることを確認。
  4. 文字入力を開始。
    • オートコンプリートの候補が表示されることを確認。

4. 複数モデルでの動作確認

上記「1〜3」の確認手順を、以下の各モデルのページで同様に行い、コンポーネントが汎用的に動作することを確認。

  • User モデル(例: /users/kimura
  • Doc モデル(例: /docs/(任意のDocのID)
  • Question モデル(例: /questions/(任意のQuestionのID)
  • Movie モデル(例: /movies/(任意のMovieのID)

※注意:Movieモデルのリンクエラーについて

Movieモデルのページでタグのリンクをクリックすると、ルーティングエラーが発生します。
これは、元のReact版でも同様の挙動であり、現在本番環境では動画が存在していないため、今回の修正範囲には含まず、意図的にこの状態を維持しています。

Screenshot

機能の置き換えであり、ユーザーから見た挙動や見た目に変更はないため、スクリーンショットはありません。

Summary by CodeRabbit

  • 新機能

    • タグ編集UIが新しいサーバーサイドRubyコンポーネントとして実装され、タグの表示・編集が可能になりました。
    • タグ編集用のフォームや操作ボタン、警告メッセージを含むUIが追加されました。
  • リファクタ

    • タグ表示・編集機能がReactコンポーネントからRuby ViewComponentへ移行され、UIの一貫性と保守性が向上しました。
    • タグのバリデーションや変換処理が独立したシンプルな関数に整理されました。
    • タグ管理のJavaScriptモジュールが刷新され、タグの取得・更新・検証・変換処理が明確に分離されました。
  • 削除

    • 旧React製のタグ編集コンポーネントが削除されました。

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jul 3, 2025

"""

Walkthrough

タグ編集UIの実装がReactコンポーネントからRuby ViewComponentと純粋なJavaScript(Tagify利用)へ全面的に移行されました。タグのバリデーション・変換・パース・API通信などのロジックも個別のJSモジュールとして再構成されています。関連するビューやヘルパーもReact依存から脱却しています。

Changes

ファイル群 変更内容概要
app/javascript/components/Tags/Tags.jsx Reactタグ編集コンポーネントの削除
app/views/movies/_movie_header.html.slim
app/views/pages/_doc_header.html.slim
app/views/questions/_question_header.html.slim
app/views/users/show.html.slim
Reactタグコンポーネント呼び出しを削除し、Ruby ViewComponent(Tag::FormComponent)によるタグUIに置換
app/components/tag/form_component.html.slim
app/components/tag/form_component.rb
新規: タグ編集用ViewComponent(Slimテンプレート+クラス)追加
app/javascript/tag.js 新規: Tagifyを用いたタグ編集・表示・API通信のJSモジュール追加
app/javascript/parse_tags.js 新規: カンマ区切り文字列を配列に変換する関数追加
app/javascript/transform-head-sharp.js 新規: 先頭がシャープ等なら除去する関数追加
app/javascript/validate-tag-name.js オブジェクトメソッドから関数型へリファクタリング、バリデーションロジック簡素化
app/javascript/head-is-sharp-or-octothorpe.js オブジェクトメソッドから関数型へリファクタリング、正規表現簡素化
app/javascript/packs/application.js 新規tag.jsのimport追加

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant Browser
  participant TagJS
  participant Server

  User->>Browser: 「タグ編集」ボタンをクリック
  Browser->>TagJS: タグ編集UIを表示
  User->>TagJS: タグを編集
  TagJS->>TagJS: バリデーション・変換処理
  User->>TagJS: 保存ボタン押下
  TagJS->>Server: PUT /api/tags (新タグリスト送信)
  Server-->>TagJS: 更新結果レスポンス
  TagJS->>Browser: タグリスト再描画・編集UIを隠す
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~45 minutes

Suggested reviewers

  • komagata

Poem

🐰
タグの森に春がきて
Reactうさぎは旅立った
ルビーの魔法とJSの種
新しいタグが咲きほこる
みんなで編集、ピョンと保存
うさぎもびっくり、ふわふわ進化!
#TagLife
"""

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)
test/components/tag/form_component_test.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/components/tag/form_component.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

'

Note

⚡️ Unit Test Generation - Beta

CodeRabbit's unit test generation is now available in Beta! Automatically generate comprehensive unit tests for your code changes, ensuring better test coverage and catching edge cases you might miss. Our AI analyzes your code structure and creates tests that follow best practices and your project's testing patterns. Learn more here, or just try it under ✨ Finishing Touches.


📜 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 b5c2ab1 and 2d23fac.

📒 Files selected for processing (14)
  • app/components/tag/form_component.html.slim (1 hunks)
  • app/components/tag/form_component.rb (1 hunks)
  • app/javascript/components/Tags/Tags.jsx (0 hunks)
  • app/javascript/head-is-sharp-or-octothorpe.js (1 hunks)
  • app/javascript/packs/application.js (1 hunks)
  • app/javascript/parse_tags.js (1 hunks)
  • app/javascript/tag.js (1 hunks)
  • app/javascript/transform-head-sharp.js (1 hunks)
  • app/javascript/validate-tag-name.js (1 hunks)
  • app/views/movies/_movie_header.html.slim (1 hunks)
  • app/views/pages/_doc_header.html.slim (1 hunks)
  • app/views/questions/_question_header.html.slim (1 hunks)
  • app/views/users/show.html.slim (1 hunks)
  • test/components/tag/form_component_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • app/javascript/components/Tags/Tags.jsx
🚧 Files skipped from review as they are similar to previous changes (13)
  • app/javascript/packs/application.js
  • app/javascript/parse_tags.js
  • app/components/tag/form_component.html.slim
  • app/views/users/show.html.slim
  • app/views/questions/_question_header.html.slim
  • app/views/movies/_movie_header.html.slim
  • app/javascript/head-is-sharp-or-octothorpe.js
  • app/javascript/transform-head-sharp.js
  • app/views/pages/_doc_header.html.slim
  • test/components/tag/form_component_test.rb
  • app/javascript/validate-tag-name.js
  • app/components/tag/form_component.rb
  • app/javascript/tag.js
⏰ 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-tags-implementation

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.

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

🧹 Nitpick comments (4)
app/javascript/parse_tags.js (1)

4-4: 不要なmapメソッドを削除することで処理を簡潔化できます。

現在の実装ではmap((value) => value)で値をそのまま返しているため、この処理は冗長です。

以下の修正により処理をより簡潔にできます:

-  return value.split(',').map((value) => value)
+  return value.split(',')
app/views/movies/_movie_header.html.slim (1)

77-77: 不要な.to_sの呼び出しを削除してください。

ViewComponentへの移行は正しく実装されていますが、join(',')は既に文字列を返すため、.to_sの呼び出しは不要です。

-        = render(Tag::TagComponent.new(initial_tags: movie.tag_list.join(',').to_s, param_name: 'movie[tag_list]', input_id: 'movie_tag_list', taggable_type: 'Movie', taggable_id: movie.id.to_s))
+        = render(Tag::TagComponent.new(initial_tags: movie.tag_list.join(','), param_name: 'movie[tag_list]', input_id: 'movie_tag_list', taggable_type: 'Movie', taggable_id: movie.id.to_s))
app/javascript/tag.js (2)

36-53: タグレンダリング処理のパフォーマンスを改善してください

現在の実装では、タグをレンダリングするたびにDOM要素の検索と削除を行っています。DocumentFragmentを使用することで、より効率的にDOM操作を行えます。

以下の改善を検討してください:

 const renderTags = (tags) => {
   const items = tagListItems.querySelectorAll('.tag-links__item')
   items.forEach((item) => {
     if (!item.querySelector('.tag-links__item-edit')) {
       item.remove()
     }
   })

+  const fragment = document.createDocumentFragment()
   tags.forEach((tag) => {
     const li = document.createElement('li')
     li.className = 'tag-links__item'
     li.innerHTML = `<a class="tag-links__item-link" href="/${tagsType.toLowerCase()}s/tags/${encodeURIComponent(
       tag
     )}">${tag}</a>`
-    const editBtnLi = editButton?.parentElement
-    tagListItems.insertBefore(li, editBtnLi || null)
+    fragment.appendChild(li)
   })
+  
+  const editBtnLi = editButton?.parentElement
+  tagListItems.insertBefore(fragment, editBtnLi || null)
 }

80-82: ユーザーエクスペリエンスの改善を検討してください

alert()を使用したエラー表示は、ユーザビリティの観点から改善の余地があります。より適切なUI要素(トーストメッセージやインライン表示)を使用することを検討してください。

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 07f6de0 and 3431dd0.

📒 Files selected for processing (19)
  • app/components/tag/tag_component.html.slim (1 hunks)
  • app/components/tag/tag_component.rb (1 hunks)
  • app/controllers/welcome_controller.rb (3 hunks)
  • app/javascript/components/Tags/Tags.jsx (0 hunks)
  • app/javascript/head-is-sharp-or-octothorpe.js (1 hunks)
  • app/javascript/packs/application.js (1 hunks)
  • app/javascript/parse_tags.js (1 hunks)
  • app/javascript/tag.js (1 hunks)
  • app/javascript/transform-head-sharp.js (1 hunks)
  • app/javascript/validate-tag-name.js (1 hunks)
  • app/views/movies/_movie_header.html.slim (1 hunks)
  • app/views/pages/_doc_header.html.slim (1 hunks)
  • app/views/questions/_question_header.html.slim (1 hunks)
  • app/views/users/show.html.slim (1 hunks)
  • app/views/welcome/certified_reskill_courses/rails_developer_course/_faq.html.slim (1 hunks)
  • app/views/welcome/certified_reskill_courses/rails_developer_course/index.html.slim (1 hunks)
  • app/views/welcome/faqs/_faqs_empty.html.slim (1 hunks)
  • db/fixtures/faq_categories.yml (1 hunks)
  • db/fixtures/faqs.yml (1 hunks)
💤 Files with no reviewable changes (1)
  • app/javascript/components/Tags/Tags.jsx
🧰 Additional context used
🧠 Learnings (7)
📓 Common learnings
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8771
File: app/controllers/welcome_controller.rb:57-57
Timestamp: 2025-06-30T01:07:46.170Z
Learning: プロジェクトでは、仕様上データの存在が保証されている場合、nil処理を省略することがある。特にFAQ表示のような特定機能に特化したPRでは、データの存在を前提とした実装が採用される。
app/views/welcome/certified_reskill_courses/rails_developer_course/_faq.html.slim (2)
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8771
File: app/controllers/welcome_controller.rb:57-57
Timestamp: 2025-06-30T01:07:46.170Z
Learning: プロジェクトでは、仕様上データの存在が保証されている場合、nil処理を省略することがある。特にFAQ表示のような特定機能に特化したPRでは、データの存在を前提とした実装が採用される。
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
app/components/tag/tag_component.html.slim (1)
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
app/controllers/welcome_controller.rb (1)
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8771
File: app/controllers/welcome_controller.rb:57-57
Timestamp: 2025-06-30T01:07:46.170Z
Learning: プロジェクトでは、仕様上データの存在が保証されている場合、nil処理を省略することがある。特にFAQ表示のような特定機能に特化したPRでは、データの存在を前提とした実装が採用される。
app/views/movies/_movie_header.html.slim (1)
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
app/views/welcome/faqs/_faqs_empty.html.slim (1)
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8771
File: app/controllers/welcome_controller.rb:57-57
Timestamp: 2025-06-30T01:07:46.170Z
Learning: プロジェクトでは、仕様上データの存在が保証されている場合、nil処理を省略することがある。特にFAQ表示のような特定機能に特化したPRでは、データの存在を前提とした実装が採用される。
db/fixtures/faqs.yml (1)
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8771
File: app/controllers/welcome_controller.rb:57-57
Timestamp: 2025-06-30T01:07:46.170Z
Learning: プロジェクトでは、仕様上データの存在が保証されている場合、nil処理を省略することがある。特にFAQ表示のような特定機能に特化したPRでは、データの存在を前提とした実装が採用される。
🪛 ESLint
app/javascript/validate-tag-name.js

[error] 3-3: Irregular whitespace not allowed.

(no-irregular-whitespace)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build_and_test
🔇 Additional comments (15)
app/javascript/packs/application.js (1)

82-82: 新しいタグ編集機能の統合が適切に行われています。

ReactベースのタグコンポーネントからVanilla JavaScriptによる実装への移行に合わせて、新しいタグ編集モジュールが正しくインポートされています。

app/components/tag/tag_component.html.slim (1)

1-23: タグコンポーネントのSlimテンプレートが適切に実装されています。

ReactコンポーネントからRailsViewComponentへの移行において、以下の点が適切に実装されています:

  • 表示モードと編集モードの適切な分離
  • JavaScript初期化のためのdata属性の設定
  • フォームの初期状態が非表示になっている
  • 保存・キャンセルボタンの適切な配置
app/javascript/head-is-sharp-or-octothorpe.js (1)

1-6: 関数のリファクタリングが適切に行われています。

以下の改善により、関数がより堅牢になりました:

  • null/falsy値のチェック追加によるエラー防止
  • 不要な.*を削除した正規表現の簡略化
  • オブジェクトエクスポートから関数エクスポートへの変更
app/views/users/show.html.slim (1)

50-50: ReactコンポーネントからRailsViewComponentへの移行が正しく実装されています。

Tag::TagComponentの呼び出しにおいて、元のReactコンポーネントのpropsが適切にマッピングされており、編集権限の判定も正しく行われています。

app/views/questions/_question_header.html.slim (1)

74-74: Reactコンポーネントからの移行が正しく実装されています。

新しいRails ViewComponentへの移行が適切に行われており、必要なパラメータが正しく渡されています。

app/components/tag/tag_component.rb (1)

1-16: ViewComponentの実装が適切です。

新しいTag::TagComponentクラスは、必要なパラメータを適切に初期化し、ViewComponentの規約に従って実装されています。editable?メソッドも明確で使いやすいインターフェースを提供しています。

app/javascript/tag.js (1)

1-128: 全体的な実装品質について

React からVanilla JavaScriptへの移行により、コードの可読性と保守性が向上しています。Tagifyライブラリの適切な使用と、CSRFトークンの取り扱いも正しく実装されています。

db/fixtures/faq_categories.yml (1)

29-31: 新しいFAQカテゴリの追加が適切です

新しいFAQカテゴリ「給付制度対象講座について」の追加は、既存のパターンに従い、position値も適切に設定されています。

app/views/welcome/certified_reskill_courses/rails_developer_course/index.html.slim (1)

51-54: FAQセクションの条件付きレンダリングが適切です

FAQが存在する場合の表示と、管理者向けの空状態表示の条件分岐が適切に実装されています。UXの観点からも良い設計です。

app/views/welcome/certified_reskill_courses/rails_developer_course/_faq.html.slim (2)

1-22: FAQパーシャルの構造は適切です

HTMLの構造とCSS클래스の使用は一貫性があり、既存のコードスタイルに適合しています。


20-21: MarkdownInitializerの実装確認をお願いします

JavaScript側で.js-markdown-viewに対してMarkdownInitializerを適用していますが、実際にマークダウン変換処理と必要なサニタイズが行われているかをご確認ください。

  • 確認対象ファイル:app/javascript/markdown.js
    new MarkdownInitializer().replace('.js-markdown-view') の呼び出し
  • MarkdownInitializer モジュールの定義箇所を見つけ、
    ・マークダウン→HTML変換(例:marked 等)が正しく実装されているか
    ・XSS対策としてHTMLサニタイズが含まれているか
app/views/welcome/faqs/_faqs_empty.html.slim (1)

1-19: 空状態のUIが適切に実装されています

管理者向けの空状態表示は、適切なUXパターンを使用しており、コンテンツ管理のためのコールトゥアクションも含まれています。

app/controllers/welcome_controller.rb (2)

8-9: 定数の分割が適切です

FAQ_CATEGORY_NAMEを用途別に分割することで、コードの可読性と保守性が向上しています。


37-37: FAQカテゴリ「法人利用について」はfixturesで定義されているため、nilチェックは不要です

  • app/controllers/welcome_controller.rb:37
    FAQCategory.find_by(name: FAQ_CATEGORY_NAME_FOR_CORPORATE)
    db/fixtures/faq_categories.yml に faq_categories7: name: 法人利用について として登録済みのため、常に存在します。
db/fixtures/faqs.yml (1)

225-240: faq_categories8 は既に定義済みです
db/fixtures/faq_categories.yml の29行目に "faq_categories8:" が存在するため、fixture ロード時にエラーは発生しません。特に修正は不要です。

Likely an incorrect or invalid review comment.

@e-yanagita-gs e-yanagita-gs force-pushed the chore/replace-tags-implementation branch from 3431dd0 to a5a020e Compare July 3, 2025 12:49
@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
お疲れ様です!
こちら、レビューをお願いすることは可能でしょうか?

@e-yanagita-gs e-yanagita-gs self-assigned this Jul 4, 2025
@smallmonkeykey
Copy link
Copy Markdown
Contributor

@e-yanagita-gs
お疲れ様です!
初めてのレビューになるため、少しお時間をいただくかもしれませんが、火曜日までにはお返事できるようにします。
それでもよろしければ、レビューを担当させてください🙏✨

@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
ありがとうございます!
時間については大丈夫です😆
どうぞよろしくお願いいたします!

Copy link
Copy Markdown
Contributor

@smallmonkeykey smallmonkeykey left a comment

Choose a reason for hiding this comment

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

非React化お疲れ様です!!
かなりレビューに時間がかかってしまいお待たせしました🙇‍♂️
レビューしましたのでご確認よろしくお願いいたします。

また、動作確認を行ったのですがタグの保存がされない時がありました。
以下はdevelop環境下で試した動画です。
https://www.awesomescreenshot.com/video/41809160?key=c8f0dbc910ddc388f0a299ba743fbd53
保存される時もあるのですが、おそらく早く打つと保存がされないのかなと考えています。

ちなみに本番環境下(私のフィヨルドの実際のページ)でも同様に保存されない時がありました。
https://www.awesomescreenshot.com/video/41808366?key=3275a533becc9ead379974ad358247a4

どこが問題なのかかなり調査したのですが、まだ原因がわからず、火曜日までに一旦お返事すると約束したので、一旦現状どのような状況下であるかをお伝えしました。
恐れ入れますが、保存周りを再度確認いただければと思います。

@@ -0,0 +1,5 @@
export default function transformHeadSharp(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.

現在の transformHeadSharp という名前からは具体的な動作が少しわかりにくいため、

  • 具体的な名前であれば removeHeadSharp
  • 今回のようにもう少し抽象的で目的ベースの名前にするのであればextractTagName
    の方がより意図が伝わりやすいのではないかと思いました 👀

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.

フィードバックありがとうございます!
また、removeHeadSharpextractTagName といった具体的な代替案までいただき、大変参考になります。

おっしゃる通り、関数名としてはご提案いただいた名前の方が処理内容を的確に表していると思います。

その上でご相談なのですが、今回この関数名を維持したいのには理由があります。
実は、この関数は将来的に削除の可能性がある旧ファイル(app/javascript/components/Tags/transform-head-sharp.js)の役割を引き継ぐものです。

旧ファイルの削除は今回のIssueの範囲外と判断し見送ったのですが、いずれ削除する際に、この新しい関数が後継の処理であることが一目で分かるように、あえて同じ名前を採用しています。

このような背景なのですが、このままの関数名で進めさせていただくのはいかがでしょうか。

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.

なるほどです👀そのような理由があったのですね!
そのような拝見があれば、このままの関数名で良いと思います👍
説明してくださってありがとうございます🙏

try {
const url = `/api/tags.json?taggable_type=${tagsType}`
const data = await fetcher(url)
tagify.settings.whitelist = data.map((tag) => tag.value)
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.

Tagifyの公式ドキュメントによるとtagify.settings.whitelistではなくtagify.whitelistをのほうを推奨しているみたいなので確認お願いします🙏

https://github.com/yairEO/tagify?tab=readme-ov-file#faq

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.

tagify.whitelistに修正しました!
ありがとうございます。

@editable = editable
end

def initial_tags
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.

質問です🙋‍♀️
attr_readerを使われているので@を付けずに呼び出しが可能だとは思うのですが、何か理由はありますか?👀

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.

ご指摘ありがとうございます!
純粋に不要な@を削除し忘れておりましたので、修正いたしました🙇‍♀️

@smallmonkeykey
Copy link
Copy Markdown
Contributor

@e-yanagita-gs
お疲れ様です。夜分にすみません🙇‍♂️
レビューしましたのでご確認お願いいたします🙏

@e-yanagita-gs e-yanagita-gs force-pushed the chore/replace-tags-implementation branch from c3cd028 to bcb0558 Compare July 9, 2025 01:11
@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
こちら、丁寧なご確認ありがとうございます🙇‍♀️
私も同様の挙動が確認できないか試したのですが、開発環境・本番環境のいずれでもタグが保存されない挙動は確認できませんでした...
動画を見ていると、タグ保存の後左上にあるボタンか何かをタップされた後にタグが消えているように見えるのですが、タグ保存後にどういった作業をされていらっしゃるか教えていただけないでしょうか?

@smallmonkeykey
Copy link
Copy Markdown
Contributor

@e-yanagita-gs
ご確認ありがとうございます!
左上、画面外で見えませんでしたね。すみません🙇‍♂️
私が左上で行っていたのは、リロードボタンのクリックでした。

タグについてですが、データベースに保存される仕様だと思っています。
その場合、リロードボタンを押してもタグは消えないはずですが、見かけ上は保存されているように見えても、実際にはデータベースに保存されていないことがありました。

ただ、毎回保存に失敗するわけではなく、「入力してすぐに保存ボタンを押したとき」に保存されないことが起きているようでした。

@e-yanagita-gs e-yanagita-gs force-pushed the chore/replace-tags-implementation branch from bcb0558 to 4e73d6c Compare July 10, 2025 05:40
@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

e-yanagita-gs commented Jul 10, 2025

@smallmonkeykey

レビューありがとうございます。
ご指摘いただいた「タグを素早く更新すると保存されない」現象について、本番環境でも再現することを確認いたしました。
原因を調査したところ、この問題はプログラムが処理を実行する順番が関係していると考えられます。

不具合の発生条件

今回の不具合は、タグ入力欄に新しいテキストを入力した後、Enterキーなどでタグを確定させずに、即座に「保存する」ボタンを押したときに発生しました。

不具合の原因

従来の実装では、

  1. タグの内容をJavaScriptの変数に反映させる処理
  2. 保存ボタンが押されたときに、その変数の内容をサーバーへ送る処理

という2段階のステップになっていました。

しかし、不具合の発生条件を満たす操作を行うと、①の「変数への反映」が終わる前に、②の「サーバーへ送る」処理が先に動いてしまうことがありました。その結果、更新される前の古いデータが保存されてしまう、という問題が発生してしまったと考えられます。


今回の解決策

この問題を解決するため、tag.jssubmitイベントハンドラを修正しました。

JavaScriptの変数を経由するのをやめ、保存ボタンが押された瞬間のTagify入力欄の最新の値 (tagify.value) を直接取得し、それを元にAPIリクエストを送信するように変更しました。

これにより、処理のタイミングに依存することなく、常にユーザーの入力と同期が取れた最新のデータが保存されるようになります。


修正後、私の開発環境では、従来不具合が発生していた状況でも不具合が解消されていることを確認済みです。
お手数ですが、ご確認のほど、よろしくお願いいたします。

@smallmonkeykey
Copy link
Copy Markdown
Contributor

@e-yanagita-gs
不具合の修正ありがとうございます!また、解決策も丁寧に書いてくださり、とてもわかりやすかったです🙌
こちらでも不具合が解消されているのを確認できたので、Approveさせていただきます。
お疲れさまでした🙏

@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@smallmonkeykey
細かい挙動の確認までありがとうございました!
また、コードに対しても随時公式リファレンスと照らして確認していただくなど丁寧なチェックをいただき、
その姿勢が大変刺激になりましたし、よりよいコードにするきっかけをいただき感謝しています。
今後とも、どうぞよろしくお願いいたします🙇‍♀️

@komagata
お疲れ様です!
メンバーレビューをクリアしましたので、ご確認よろしくお願いいたします。

@e-yanagita-gs e-yanagita-gs requested a review from komagata July 11, 2025 06:33
@@ -0,0 +1,30 @@
# frozen_string_literal: true
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

TagComponentというとTag表示部分が第一に浮かんでくると思うので「タグの入力」のComponentということを示す名前がいいかなと思いました。

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.

ありがとうございます!
Tag::TagComponent の名前を、その役割がより明確に分かるようにTag::FormComponent に変更しました。

@e-yanagita-gs e-yanagita-gs force-pushed the chore/replace-tags-implementation branch from 4e73d6c to 439dada Compare July 14, 2025 08:29
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: 1

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4e73d6c and 439dada.

📒 Files selected for processing (13)
  • app/components/tag/form_component.html.slim (1 hunks)
  • app/components/tag/form_component.rb (1 hunks)
  • app/javascript/components/Tags/Tags.jsx (0 hunks)
  • app/javascript/head-is-sharp-or-octothorpe.js (1 hunks)
  • app/javascript/packs/application.js (1 hunks)
  • app/javascript/parse_tags.js (1 hunks)
  • app/javascript/tag.js (1 hunks)
  • app/javascript/transform-head-sharp.js (1 hunks)
  • app/javascript/validate-tag-name.js (1 hunks)
  • app/views/movies/_movie_header.html.slim (1 hunks)
  • app/views/pages/_doc_header.html.slim (1 hunks)
  • app/views/questions/_question_header.html.slim (1 hunks)
  • app/views/users/show.html.slim (1 hunks)
💤 Files with no reviewable changes (1)
  • app/javascript/components/Tags/Tags.jsx
✅ Files skipped from review due to trivial changes (1)
  • app/components/tag/form_component.rb
🚧 Files skipped from review as they are similar to previous changes (10)
  • app/javascript/packs/application.js
  • app/javascript/parse_tags.js
  • app/javascript/transform-head-sharp.js
  • app/views/movies/_movie_header.html.slim
  • app/views/users/show.html.slim
  • app/javascript/head-is-sharp-or-octothorpe.js
  • app/views/questions/_question_header.html.slim
  • app/views/pages/_doc_header.html.slim
  • app/javascript/validate-tag-name.js
  • app/javascript/tag.js
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
app/components/tag/form_component.html.slim (1)
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
⏰ 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 (3)
app/components/tag/form_component.html.slim (3)

1-5: データ属性の命名とコンテナ構造が適切です

JavaScript統合のためのデータ属性の設計が良好で、タグの初期値、タイプ、IDが適切に設定されています。


8-11: 編集ボタンの条件分岐が適切です

editable?メソッドによる条件分岐で編集ボタンの表示制御が適切に実装されています。


13-13: 属性値のサニタイズ状況を再確認してください

現在、param_nameinput_idinitialize でそのまま受け渡され、コンポーネント内で明示的な検証・サニタイズ処理は行われていません。Slim はデフォルトで属性値をエスケープしますが、以下を必ずご確認ください:

  • app/components/tag/form_component.rb
    def initialize(taggable:, param_name:, input_id:, …) で受け取る値が全てアプリ側で生成・管理されており、外部(ユーザー)入力が直接渡ることはないか
  • app/components/tag/form_component.html.slim (行13)
    input.tags-form__input name=param_name id=input_id value=initial_tags の属性値に意図しない文字列("<> など)が混入する可能性がないか

万一、外部入力が混ざる恐れがある場合は、許可する文字種を制限するか、ERB::Util.html_escape などで明示的にサニタイズすることを検討してください。

@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@komagata
ご確認ありがとうございます!
修正いたしましたので、ご確認ください🙇‍♀️

@e-yanagita-gs e-yanagita-gs requested a review from komagata July 14, 2025 09:27
@@ -0,0 +1,30 @@
# frozen_string_literal: true
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

view_componentには必ず対応するテストが欲しい感じです。

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.

ありがとうございます!
追加しました🙇‍♀️

@e-yanagita-gs e-yanagita-gs force-pushed the chore/replace-tags-implementation branch from 0c2707c to b5d0aca Compare July 17, 2025 02:14
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 (1)
test/components/tag/form_component_test.rb (1)

29-31: editableのテストカバレッジを改善してください

現在のテストはeditable: trueの場合のみをテストしています。editable: falseの場合もテストすることでより包括的なテストカバレッジを実現できます。

以下のテストケースを追加することを検討してください:

def test_not_editable
  component = Tag::FormComponent.new(
    taggable: @user,
    param_name: 'user[tag_list]',
    input_id: 'user_tag_list',
    editable: false
  )
  refute component.editable?
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 0c2707c and b5d0aca.

📒 Files selected for processing (14)
  • app/components/tag/form_component.html.slim (1 hunks)
  • app/components/tag/form_component.rb (1 hunks)
  • app/javascript/components/Tags/Tags.jsx (0 hunks)
  • app/javascript/head-is-sharp-or-octothorpe.js (1 hunks)
  • app/javascript/packs/application.js (1 hunks)
  • app/javascript/parse_tags.js (1 hunks)
  • app/javascript/tag.js (1 hunks)
  • app/javascript/transform-head-sharp.js (1 hunks)
  • app/javascript/validate-tag-name.js (1 hunks)
  • app/views/movies/_movie_header.html.slim (1 hunks)
  • app/views/pages/_doc_header.html.slim (1 hunks)
  • app/views/questions/_question_header.html.slim (1 hunks)
  • app/views/users/show.html.slim (1 hunks)
  • test/components/tag/form_component_test.rb (1 hunks)
💤 Files with no reviewable changes (1)
  • app/javascript/components/Tags/Tags.jsx
🚧 Files skipped from review as they are similar to previous changes (12)
  • app/javascript/parse_tags.js
  • app/components/tag/form_component.html.slim
  • app/views/movies/_movie_header.html.slim
  • app/javascript/packs/application.js
  • app/views/questions/_question_header.html.slim
  • app/views/users/show.html.slim
  • app/components/tag/form_component.rb
  • app/javascript/validate-tag-name.js
  • app/views/pages/_doc_header.html.slim
  • app/javascript/transform-head-sharp.js
  • app/javascript/tag.js
  • app/javascript/head-is-sharp-or-octothorpe.js
🧰 Additional context used
📓 Path-based instructions (2)
**/*.rb

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

test/**/*

Instructions used from:

Sources:
⚙️ CodeRabbit Configuration File

🧠 Learnings (1)
📓 Common learnings
Learnt from: e-yanagita-gs
PR: fjordllc/bootcamp#8881
File: app/javascript/transform-head-sharp.js:1-8
Timestamp: 2025-07-04T01:28:44.174Z
Learning: Tagifyライブラリは空文字列のタグを自動的に追加しないという仕様があるため、変換処理で空文字列を生成することで不要なタグの追加を防ぐことができる。
Learnt from: tyrrell-IH
PR: fjordllc/bootcamp#8807
File: app/views/welcome/job_support.html.slim:391-392
Timestamp: 2025-06-21T22:30:20.116Z
Learning: このプロジェクトにはRailsの組み込みmarkdownヘルパが利用できないため、markdownのHTML変換には自前でヘルパを実装する必要がある。
🧬 Code Graph Analysis (1)
test/components/tag/form_component_test.rb (1)
app/components/tag/form_component.rb (4)
  • initial_tags (11-13)
  • taggable_type (15-17)
  • taggable_id (19-21)
  • editable? (23-25)
⏰ 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 (5)
test/components/tag/form_component_test.rb (5)

1-15: セットアップが適切に実装されています

ViewComponentのテストパターンに従って正しく実装されており、必要なパラメータを持つコンポーネントインスタンスが適切に作成されています。


17-19: initial_tagsメソッドのテストが適切です

タグリストがカンマ区切りの文字列として正しく返されることを検証しており、適切な単体テストになっています。


21-23: taggable_typeメソッドのテストが適切です

taggableオブジェクトのクラス名が文字列として正しく返されることを検証しています。


25-27: taggable_idメソッドのテストが適切です

IDが文字列形式で正しく返されることを検証しており、JavaScript連携において重要な機能をテストしています。


5-32: テストクラス全体の構造が良好です

コーディングガイドラインに従って、ViewComponentのメソッド追加に対応する単体テストが適切に実装されています。すべての主要メソッドがカバーされており、テストケース名も英語で記述されています。

@e-yanagita-gs e-yanagita-gs requested a review from komagata July 17, 2025 03:46
@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@komagata
テストコードを追加しました!
ご確認よろしくお願いいたしますm(_ _)m

@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@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 27c4db6 into main Jul 24, 2025
5 checks passed
@komagata komagata deleted the chore/replace-tags-implementation branch July 24, 2025 07:14
@github-actions github-actions bot mentioned this pull request Jul 24, 2025
87 tasks
@e-yanagita-gs
Copy link
Copy Markdown
Contributor Author

@komagata
ありがとうございます!!!✨

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