背景
cookpad_all では Rails 6.0 で zeitwerk を使っている状況で Chanko を使っています。
また Chanko::Config の設定については config/initializers 以下に Chanko 用のファイルを用意してそこで各種値を設定しており、そこで unit を置くディレクトリを Chanko::Config.units_directory_path = "app/extensions" で変更しています。
問題
上で設定した units_directory_path が反映されず、デフォルトである app/units で固定されてしまいます。
原因
Chanko::Config は一度 units_directory_path を読み出そうとしたタイミングで現在の @units_directory_path の値をキャッシュしています。
|
def units_directory_path |
|
@resolved_units_directory_path ||= Rails.root.join(@units_directory_path).to_s |
|
end |
また、zeitwerk 環境下では以下のコードにより before: :set_autoload_paths のタイミングで Chanko::Loader.prepare_eager_load が呼び出されます。これは initializers 以下のコードが実行されるよりも前のタイミングです。
|
initializer("chanko.zeitwerk.prepare_eager_load", before: :set_autoload_paths) do |app| |
|
# zeitwerk freezes autoload_paths after :set_autoload_paths. |
|
# So we need to prepare before set_autoload_paths |
|
Chanko::Loader.prepare_eager_load(mode: :zeitwerk) |
|
end |
この prepare_eager_load の中で Chanko::Config::units_directory_path が読み出されているんですが、その時点ではまだ units_directory_path がデフォルト値なのでそちらの値でパスが固定されます。
|
Rails.autoloaders.main.collapse(Chanko::Config.units_directory_path + '/*') |
確認したいこと
- この仕様は意図したしようでしょうか。
- もし意図した挙動であれば少しハマりやすいポイントなので、以下のような対応をしたいです。
- ドキュメントにパスの設定は initializers ではなく application.rb や environment などに書くことを記述する。
@resolved_units_directory_path に一度値が入ってしまった場合、 @units_directory_path にいくら値を入れても Chanko で利用するパスは変更できないので、units_directory_path=(path) で @resolved_units_directory_path が nil でないときに例外を吐くなどをしたい。
- もし意図していない挙動であればちょっと修正方針を考えたいです。
背景
cookpad_all では Rails 6.0 で zeitwerk を使っている状況で Chanko を使っています。
また
Chanko::Configの設定についてはconfig/initializers以下に Chanko 用のファイルを用意してそこで各種値を設定しており、そこで unit を置くディレクトリをChanko::Config.units_directory_path = "app/extensions"で変更しています。問題
上で設定した
units_directory_pathが反映されず、デフォルトであるapp/unitsで固定されてしまいます。原因
Chanko::Configは一度units_directory_pathを読み出そうとしたタイミングで現在の@units_directory_pathの値をキャッシュしています。chanko/lib/chanko/config.rb
Lines 34 to 36 in f6fdda4
また、zeitwerk 環境下では以下のコードにより
before: :set_autoload_pathsのタイミングでChanko::Loader.prepare_eager_loadが呼び出されます。これはinitializers以下のコードが実行されるよりも前のタイミングです。chanko/lib/chanko/railtie.rb
Lines 18 to 22 in f6fdda4
この
prepare_eager_loadの中でChanko::Config::units_directory_pathが読み出されているんですが、その時点ではまだunits_directory_pathがデフォルト値なのでそちらの値でパスが固定されます。chanko/lib/chanko/loader.rb
Line 46 in f6fdda4
確認したいこと
@resolved_units_directory_pathに一度値が入ってしまった場合、@units_directory_pathにいくら値を入れても Chanko で利用するパスは変更できないので、units_directory_path=(path)で@resolved_units_directory_pathが nil でないときに例外を吐くなどをしたい。