231

/lib開発中にディレクトリ内のコードを自動ロードするために、初期化子で次の行を使用します。

config/initializers/custom.rb:

RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?

( Rails 3 クイックヒント: 開発モードで lib フォルダーを自動リロードするより)

うまく機能しますが、本番環境で使用するには非効率的です。リクエストごとにライブラリをロードする代わりに、起動時にライブラリをロードしたいだけです。同じブログには、これを行う方法を説明する別の記事があります。

config/application.rb:

# Custom directories with classes and modules you want to be autoloadable.
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]

しかし、それに切り替えると、開発中であっても、lib 関数を使用しようとすると NoMethodErrors が発生します。

私のlibファイルの例:

lib/extensions.rb:

Time.class_eval do
  def self.milli_stamp
    Time.now.strftime('%Y%m%d%H%M%S%L').to_i
  end
end

呼び出すTime.milli_stampと NoMethodError がスローされます

他の人が SO に関する同様の質問に回答していることに気付きましたが、それらはすべて命名規則や、以前は心配する必要がなかったその他の問題に対処しているようです。私の lib クラス、リクエストごとの読み込みで既に機能していました。起動ごとの読み込みに。これを行う正しい方法は何ですか?

4

4 に答える 4

550

これで問題が解決すると思います:

  1. config/application.rbで:

    config.autoload_paths << Rails.root.join('lib')
    

    libで正しい命名規則を維持します。

    lib/foo.rbで:

    class Foo
    end
    

    lib/foo/bar.rbで:

    class Foo::Bar
    end
    
  2. 本当にlib/extensions.rbのようなファイルにいくつかのモンキー パッチを適用したい場合は、手動で必要にすることができます。

    config/initializers/require.rbで:

    require "#{Rails.root}/lib/extensions" 
    

PS

于 2013-10-29T05:41:39.967 に答える
33

これは質問に直接答えるものではありませんが、質問を完全に回避することは良い選択肢だと思います。

autoload_pathsすべてのまたは面倒を避けるために、eager_load_paths「app」ディレクトリの下に「lib」または「misc」ディレクトリを作成します。そこに通常どおりにコードを配置すると、Rails はモデル ファイルをロード (およびリロード) するのと同じようにファイルをロードします。

于 2014-09-25T10:27:34.293 に答える
6

これは、Rails がクラスの読み込みを処理する方法の解決策を検索するときにこの答えを見つけた私のような誰かを助けるかもしれません...module単にクラスを定義するのではなく、名前がファイル名と適切に一致する を定義する必要があることがわかりました。

lib/development_mail_interceptor.rbファイル内(はい、Railscast のコードを使用しています:))

module DevelopmentMailInterceptor
  class DevelopmentMailInterceptor
    def self.delivering_email(message)
      message.subject = "intercepted for: #{message.to} #{message.subject}"
      message.to = "myemail@mydomain.org"
    end
  end
end

動作しますが、クラスをモジュール内に配置していないとロードされません。

于 2014-01-24T05:28:05.677 に答える