🐷

カスタムCopを作ったらRailsのAuto-Loadにハマった

2024/08/08に公開

起こった問題

カスタム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とは

https://railsguides.jp/autoloading_and_reloading_constants.html
Railsはrequireが必要な箇所でも必要に応じてクラスやモジュールを自動読み込みをしてくれます。
RailsでAuto-Loadが行われるファイルはRailsが定義しているものになります。

回避方法

回避するには作成したCustomCopの先頭に以下の条件分岐を入れます。

return unless defined?(::RuboCop)

もしくはRailsのAuto-Loadが読み込まないlib以外のディレクトリに移動します。

定義されているかで条件分岐を行うが嫌だったので自分は後者を選んでいます。

GitHubで編集を提案
SMARTCAMP Engineer Blog

Discussion