開発中に/lib
ディレクトリにコードを自動ロードするには、イニシャライザで次の行を使用します。
config/initializers/custom.rb:
RELOAD_LIBS = Dir[Rails.root + 'lib/**/*.rb'] if Rails.env.development?
( Rails 3 Quicktipから:開発モードでlibフォルダーを自動的にリロードする )
これはうまく機能しますが、プロダクションで使用するには非効率的です。リクエストごとに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ファイルの1つの例:
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クラスはすでにworkリクエストごとのロードの場合は、 - startuploadingごとに変更します。これを行うための正しい方法は何ですか?
私はこれがあなたの問題を解決するかもしれないと思います:
config/application.rbに:
config.autoload_paths << Rails.root.join('lib')
そして正しい命名規則をlibで守ってください。
inlib/foo.rb:
class Foo
end
lib/foo/bar.rbに:
class Foo::Bar
end
あなたが本当にlib/extensions.rbのようなファイルでいくつかのモンキーパッチをやりたいなら、あなたはそれを手動で必要とするかもしれません:
inconfig/initializers/require.rb:
require "#{Rails.root}/lib/extensions"
P.S。
そして、Railsがオートロードに関して正確に何をしているのか理解するために?
read Railsのオートロード - 動作する方法と動作しない場合 。SimonCoffeyによる。
これは直接質問に答えるものではありませんが、私はそれが質問を完全に回避するための良い代替案だと思います。
すべてのautoload_paths
またはeager_load_paths
面倒を避けるために、 "app"ディレクトリの下に "lib"または "misc"ディレクトリを作成してください。通常どおりにコードを配置します。Railsは、モデルファイルのロード(および再ロード)と同じようにファイルをロードします。
これは、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 = "[email protected]"
end
end
end
機能しますが、クラスをモジュール内に配置していなければロードされません。
開発モードでのすべてのリクエストに対して、モンキーパッチ/エクステンションをロードするにはconfig.to_prepareを使用してください。
config.to_prepare do |action_dispatcher|
# More importantly, will run upon every request in development, but only once (during boot-up) in production and test.
Rails.logger.info "\n--- Loading extensions for #{self.class} "
Dir.glob("#{Rails.root}/lib/extensions/**/*.rb").sort.each do |entry|
Rails.logger.info "Loading extension(s): #{entry}"
require_dependency "#{entry}"
end
Rails.logger.info "--- Loaded extensions for #{self.class}\n"
終わり