🐷
カスタムCopを作ったらRailsのAuto-Loadにハマった
起こった問題
カスタムCop自体は正常に動作しているが作成したカスタムCopがrails db:seed
などのコマンドを実行した際に何故かCustomCopがNameError
になる。
下記が出たエラー
NameError: uninitialized constant CustomCops::RuboCop
状況
- Rails環境
- カスタムCopは
app/lib
配下に配置されている - カスタムCopは正常に動作する
- RSpecなどのテストは設定が終わってり、正常に終了する
- カスタムCopのspecは正常に終了する
原因
RailsにはAuto-Loadという機能がありlib/
Auto-Loadに設定している場合lib/
にそのまま配置してしまうとdb:seed
やその他Railsを実行する際にNameError: uninitialized constant CustomCops::RuboCop
のようなNameErrorがでてしまいます。また開発環境のみでRuboCopを使っている場合も未定義になるのでproduction環境でNameErrorになります。
RailsのAuto-Loadとは
require
が必要な箇所でも必要に応じてクラスやモジュールを自動読み込みをしてくれます。
RailsでAuto-Loadが行われるファイルはRailsが定義しているものになります。
回避方法
回避するには作成したCustomCopの先頭に以下の条件分岐を入れます。
return unless defined?(::RuboCop)
もしくはRailsのAuto-Loadが読み込まないlib以外のディレクトリに移動します。
定義されているかで条件分岐を行うが嫌だったので自分は後者を選んでいます。
Discussion