Rails4 で lib ディレクトリの自作ライブラリを読み込めない

投稿者: Anonymous

Rails3.2からRails4.0最新バージョンに上げたところ自作で作ったライブラリが読み込めなくなりました。
作成していたライブラリは以下のようなものです。

  • lib/active_support/core_ext/object.rb

    require 'active_support/core_ext/object/hoge'
    
  • lib/active_support/core_ext/object/hoge.rb

    class Float
      def hoge(poge=0)
        moge = 10.0 ** poge
      end
    end
    

Floatを拡張したhogeメソッドを呼び出すことが出来ません。Rails3.2では動いていました。
config/application.rbにconfig.autoload_pathsを追記してみても呼び出せませんでした。
app/models/concernsにおいても駄目でした。
読み込み方法を教えて頂きたいです。

解決

Railsのバージョンの違いが原因かどうかは定かではないですが、autoload先の定数(モジュール/クラス)に対する理解があやふやになっているかと思います。

まず、autoloadするlib以下のディレクトリ構造は、定義する定数の構造と一致していなければなりません。
以下のサイトが分かりやすいと思います。
http://easyramble.com/auto-load-rails-lib.html

その点を踏まえた上で、じゃあその構造通りに定義すれば上手くいくのかといえば、そうもいきません。config.autoload_pathsにlibを追加しても、autoloadの探索先に追加されるだけであって、自動的にrequireしてくれるわけではありません。requireされるのは、(大雑把に言うと)初めてその定数にアクセスしたときです。

autoloadの挙動を理解したければ、以下のような手順で確認できます。

lib/extensions.rb

p '★★★★★★★'
module Extensions
end

rails cを実行して、コンソール上でExtensionsと入力すると、

"★★★★★★★"
=> Extensions

と表示され、ここで初めてこのファイルが読み込まれているのが分かります。

ご質問内容はFloatに対するモンキーパッチで、定義済みの定数に対するautoloadなので、結果的には明示的にrequireをしてやる必要があります。ただし、autoloadされる側でrequireを呼ぶのはバッドプラクティスなので、initializerを使用するのが定石です。

lib/extensions.rb

class Float
  def hoge(poge=0)
    moge = 10.0 ** poge
  end
end

config/initializers/require.rb

require 'extensions'

参考

回答者: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *