【Rails5】自作のディレクトリを、autoload_pathsに追加して自動読み込みさせる
独自例外を定義したクラスを、autoloadさせたかったためメモ。
手順
1、
アプリのrootにcustom_exceptions
ディレクトリを作成する。
2、
custom_exceptions/custom_exceptions.rb
を作成。
module CustomExceptions class HogeError < StandardError; end end
命名規則は、
ファイル名はスネークケース(hoge_fuga_bar) module名はパスカルケース(HogeFugaBar)
とする。
階層構造、ファイル名、呼び出し方は、
# 階層 - custom_exceptions(ディレクトリ) - custom_exceptions.rb # ファイル名 custom_exceptions/custom_exceptions.rb # 呼び出し CustomExceptions::HogeError
3、 config/application.rbに下記を追加。
config.paths.add 'custom_exceptions', eager_load: true
これは4系までの書き方のよう。
# config.autoload_paths += %W(#{config.root}/custom_exceptions)
参考 Rails5: production環境でのAutoloadの廃止 - Qiita
4、 autoload_pathsに追加されているか確認するコマンド
$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths'
実行。
$ bin/rails r 'puts ActiveSupport::Dependencies.autoload_paths' Running via Spring preloader in process 5421 /Users/takeyoshimasaru/workspace/bugtracker/app/channels /Users/takeyoshimasaru/workspace/bugtracker/app/controllers /Users/takeyoshimasaru/workspace/bugtracker/app/controllers/concerns /Users/takeyoshimasaru/workspace/bugtracker/app/jobs /Users/takeyoshimasaru/workspace/bugtracker/app/mailers /Users/takeyoshimasaru/workspace/bugtracker/app/models /Users/takeyoshimasaru/workspace/bugtracker/app/models/concerns /Users/takeyoshimasaru/workspace/bugtracker/app/serializers /Users/takeyoshimasaru/workspace/bugtracker/lib /Users/takeyoshimasaru/workspace/bugtracker/custom_exceptions <<<-------これ!
正しく認識されています。
5、
rails consoleでdefined?
メソッドを使って確認できる。
# まだCustomExceptions::HogeErrorは呼び出されていないので未定義 irb(main):003:0> defined?(CustomExceptions::HogeError) => nil # 呼び出す irb(main):004:0> CustomExceptions::HogeError => CustomExceptions::HogeError # 呼び出されているので定義済であることが確認出来る irb(main):005:0> defined?(CustomExceptions::HogeError) => "constant"
注意点
- application.rbの編集は、サーバーを再起動しないと反映されない。
- rails console内でのreload!は無意味。
- Rails5から、本番環境でのautoloadが無効化されている。 Rails5のproduction環境でlib/配下のクラス読込みがNameErrorになるのはautoloadが無効化されたからだった - Qiita
若干厄介なのは本番環境時においてはautoloadが無効化されておりeager load(rails起動時にまとめて読み込む機能)が有効で、開発環境では逆にautoloadが有効でeager loadが無効になっています。(デフォルトの設定の場合。参考: Rails アップグレードガイド | Rails ガイド) 故にautoloadとeager loadどちらでもクラスが読み込まれるようにしなければなりません