定数が読み込めないエラー (LoadError)

LoadError: Unable to autoload constant SomeModule, expected /path/to/some_module.rb to define it

エラーの内容

  1. 定数 SomeModule を評価しようとする
  2. 未ロードの場合に、some_module.rb を autoload_paths から探そうとする
  3. /path/to/some_module.rb が見つかったが、SomeModule は定義されていなかった

解決策

autoload_path に加えるパス以下に配置するファイルは、Rails の命名規則に沿って配置する。

config.autoload_paths << Rails.root.join("share")

とした場合、

# share/my_namespace/hoge.rb

module MyNamaspace
  module Hoge
  end
end

のように名前空間と一致する階層にファイルを作成することで、MyNamespace::Hoge という定数を読み込めるようになる。

自動読み込みでロードする定数は、明示的に require しない。明示的に require するとファイル変更時の再読み込みが効かなくなる。

通常のサードパーティのライブラリについては、自動読み込みされるファイルの中でrequireで読み込んでも問題ありません。Railsはサードパーティのライブラリの定数を区別するので、これらは自動読み込みの対象としてマークされません。

参考:

Railsでlib以下を読み込ませる方法とその注意点 〜名前重複の死を避けるために〜 – Qiita

定数の自動読み込みと再読み込み | Rails ガイド [公式]

自動読み込みとrequire – 定数の自動読み込みと再読み込み | Rails ガイド [公式]

相対定数

モジュール内でネストされているモジュールを順に探す

module X::Y
  module A::B
  end
end

モジュールのネストは、

[A::B, X::Y]

となる。

参考:

相対定数を解決するアルゴリズム – 定数の自動読み込みと再読み込み | Rails ガイド [公式]

絶対定数

修飾済み定数が2つのコロン :: から始まっている場合、トップレベルの定数から探す。

::ModuleA::ConstantA

ModuleA をトップレベルの定数として参照する

参考:

修飾済み定数を解決するアルゴリズム – 定数の自動読み込みと再読み込み | Rails ガイド [公式]

特異クラス内で定数を参照する

特異クラスは無名であり、新たに定数を探索する場合にはトップレベルの名前空間からしか探索しません。

module ModuleA
  class ClassA
    class << self
      Hoge
    end
  end
end

この場合、Hoge はトップレベルに定義されていなければならない。ModuleA や

参考:

特異クラス内で自動読み込みを行う – 定数の自動読み込みと再読み込み | Rails ガイド [公式]

タグ:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です