ドキュメントを読み込むのは大事、ということでRailsガイドを頭から読んでいく取り組みをしています。 各章ごとに、(Railsガイドにちゃんと書いてあるのに)知らなかった機能を雑にまとめていきます。
今回は、Rails の自動読み込みと再読み込みの章です。
config.autoload_paths
リンクはこちら
app/
下のディレクトリは自動読み込みされる。
例えばapp/samples/dummy.rb
の中でDummy
クラスを定義すると、rails consoleで起動した際などに読み込みができる。
一方で、例えばルートディレクトリ直下にsamples/dummy.rb
というファイルを作った場合、samplesディレクトリは自動読み込みの対象外なのでDummyクラスは見つからない。
この場合に、config.autoload_paths
に登録することで自動読み込みの対象にできる。
# application.rb config.autoload_paths << "#{root}/samples"
一度しか自動読み込みしないconfig.autoload_once_paths
リンクはこちら
アプリケーション起動時の一度だけ読み込まれるファイルを指定します。
config.enable_reloading = true
との関係はどうなるんだろう?と思って開発環境で試してみました。
# development.rb config.enable_reloading = true config.autoload_once_paths << "#{root}/samples"
仮に上記のように設定した場合、samples配下のファイルを修正してリロードしても修正が反映されませんでした。
reload!
リンクはこちら
reload
をするとクラスが別物になります。アプリケーション内でreload!を入れることはあんまりなさそうですが、知っておくとハマりポイントを1つ回避できそうですね。
book_1 = Book.new reload! book_2 = Book.new book_1.class.object_id #=> 245440 book_2.class.object_id #=> 462620
初期化時にリロード可能な定数を参照することは禁止
リンクはこちら
あまり使うケースがなく知らなかったのですが、config/initializers
内でActiveRecordのクラスを読み込むなどしようとするとNameError
で失敗します。
# config/initializers/sample.rb p Book.new
rails s # NameError
コードの変更(今回の例だとBook
)があった場合ごとに読み込みたい場合はconfig.to_prepare
を使えます。
# config/initializers/sample.rb Rails.application.config.to_prepare { p Book.new }
もしくは、初期化時の1度だけ読み込めば良い時はafter_initialize
を使えます。
# config/initializers/sample.rb Rails.application.config.after_initialize { p Book.new }
Zeitwerkのcollapsing(折り畳み)機能
リンクはこちら
STI継承をするときなどに使えるメソッドとしてcollapsing
が紹介されています。
これはディレクトリ構造をクラス名の名前空間に反映させたくなり場合などに使えます。
# app/models/samples/dummy.rb class Dummy; end
上記だと、本来期待されるのはSamples::Dummy
なので呼び出そうとしてもNameError
が発生します。
これを例えばコンソールでcollapsing
を試すと以下のようになります。
Dummy #=> NameError) Rails.autoloaders.main.collapse("#{Rails.root}/app/models/samples") reload! Dummy #=> Dummy
push_dirでカスタム名前空間を作成する
リンクはこちら
collapse
とは逆に、デフォルトの名前空間をディレクトリなしに作成したい時にはpush_dir
が使えます。
Railsガイドに記載の通り、サービスクラスのクラスに対して、Services::
の名前空間を必要にしたい場合、ディレクトリ構成をapp/services/services/xxx
としなくても実現できます。