- Ruby / Rails関連
ViewComponent: view_component_pathを変更するならeager_load_pathsも設定すること
現象
Rails 7.1の新規アプリにViewComponent 3.6.0を導入しました。
Evil Martiansの影響で、view_component_path
設定でコンポーネントのディレクトリをデフォルトのapp/components/
からapp/views/components/
に変更しました。ビューのコンポーネントなのでapp/views/
の下にある方が自分的にもしっくりきます。
config.view_component.view_component_path = "app/views/components"
config.view_component.raise_on_db_queries = true
なおその下のraise_on_db_queries
は、コンポーネントにうっかりDBアクセスを書いたらraiseしてくれるおすすめ設定です。
これでコンポーネントは動くようになったのですが、テストを書いて実行すると以下のエラーが発生しました。
# frozen_string_literal: true
require "test_helper"
class Parts::ButtonComponentTest < ViewComponent::TestCase
def test_component_renders_primary_button
assert_equal(
%(<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">
Primary
</button>),
render_inline(Parts::ButtonComponent.new name: "Primary", variant: :primary).css("button").to_html
)
end
end
Rebuilding...
Done in 453ms.
Running 2 tests in a single process (parallelization threshold is 50)
Started with run options --seed 61482
ERROR Parts::ButtonComponentTest#test_component_renders_primary_button (0.38s)
Minitest::UnexpectedError: NameError: uninitialized constant Parts::ButtonComponent
test/components/parts/button_component_test.rb:12:in `test_component_renders_primary_button'
2/2: [====================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.38059s
2 tests, 1 assertions, 0 failures, 1 errors, 0 skips
テストからParts::ButtonComponent
にアクセスできていないので、オートローディングがらみのようです。
参考: Rails の自動読み込みと再読み込み - Railsガイド
しかしViewComponentのドキュメントを探しても設定方法が見つかりませんでした。
解決方法
結局、view_component_path
に設定したのと同じパスをeager_load_paths
にも設定することで普通に解決しました。小ネタですみません。
# config/application.rb
config.view_component.view_component_path = "app/views/components"
config.eager_load_paths << Rails.root.join("app/views/components")
その後
せっかくなので、ViewComponentのドキュメントにもこれを追記するプルリクを投げ、しばらくしてマージしていただきました。
念のため、Rails 6.1、Rails 7.0、Rails 7.1で新規アプリを作って試し、いずれの場合もview_component_path
を変更したらeager_load_paths
の変更も必要なことを確認しておきました。