日々の記録。

プログラミングのメモや感じた事などを記録。

rails libディレクトリに配置した自作ライブラリが読み込まれないときに試したこと

前提

内容

rails で 自作ライブラリCodegenLibというライブラリを利用する際、中々ロードできなかったのでそのときのメモ。(色々な無知が重なった結果の事故)

結果

結果的には、以下に注意すること

  • application.rbにautoloadのパスを追加すること.
  • lib内のクラス構成とディレクトリ構成は一致させること.(CodegenLib::CppGenerator)なら(lib/codegenlib/cpp_generator.rb)に配置すること.
  • ディレクトリ名/ファイル名は、クラス名と一致しており小文字であること(class CppGenerator)はcpp_generator.rbとなっていること
  • 余計なrequireは記述しないこと.(railsが勝手にロードしてくれる)

動作するまでの過程

初期構成

最初のディレクトリ構成

-myapp/  
  + app/  
    + controllers/  
       +code_gen_controller.rb  
  + lib/  
     + CppGenerator.rb  
     + CppHelper.rb

CppGenerator.rb

require './CppHelper.rb'
module CodegenLib
  class CppGenerator
  end
end

code_gen_controller.rb

class CodeGenController
  def generate
    g = CodegenLib::CppGenerator.new
  end
end

application.rb

lib内のファイルをオートロードするためには「事前にapplication.rbを編集しなければいけない」、という事は知っていたのでそれを設定。

class Application < Rails::Application
  config.autoload_paths += %W(#{config.root}/lib/)

動作確認 その1

この状態で動作させると、以下の旨のメッセージがでて失敗

CodeGeneratorController::CodegenLib::CppGeneratorが見つからない

対応 その1 lib内のクラス階層とディレクトリ階層を一致させる

http://www.williambharding.com/blog/technology/rails-3-autoload-modules-and-classes-in-production/ の記事を読むとクラス階層とディレクトリ階層が一致している必要がありそうなので、libのディレクトリ構成を次のように変更した。

-myapp/  
 + app/  
    + controllers/  
       + code_gen_controller.rb  
 + lib/  
     + codegenlib/
        + CppGenerator.rb  
        + CppHelper.rb

又、モジュール名をCodegenLibからCodegenlibに変更したの、ソースも次のように修正。

CppGenerator.rb

require './CppHelper.rb'
module Codegenlib
  class CppGenerator
  end
end

code_gen_controller.rb

class CodeGenController
  def generate
    g = Codegenlib::CppGenerator.new
  end
end

動作確認 その2

Codegenlib::CppGeneratorのファイルが見つかりません

CodeGenController::CppGeneratorよりは一歩前進。

対応 その2 クラスを定義したファイルを小文字に置き換える

RailsによるアジャイルWebアプリケーション開発 4版の18.1ディレクトリ構造を確認すると、クラスやモジュールが含まれるファイルに、クラス名又はモジュール名を小文字にした名前がついていると,Railsはそのファイルを自動的にロードします とある。

上記にならって、ファイル名を変更した。

-myapp/  
 + app/  
    + controllers/  
       +code_gen_controller.rb  
 + lib/
    + codegenlib/
      + cpp_generator.rb  
      + cpp_helper.rb

cpp_generator.rb

require './cpp_helper.rb'
module Codegenlib
  class CppGenerator
  end
end

動作確認 その3

cpp_helper.rbが見つからないよ

対応 その3 余計なrequireを削除

railsが勝手にロードしてくれるので、requireを削除。

cpp_generator.rb

module Codegenlib
  class CppGenerator
  end
end

動作確認 その4 無事動作

上記修正で無事オートロードされるようになった。