Rails 4でのlibファイルの自動ロード


229

/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クラスはリクエストごとのロードですでに機能してたので、それを変更したいだけです起動ごとの読み込み。これを行う正しい方法は何ですか?


Railsアプリの起動時にconfig / initializersフォルダーが自動的に読み込まれますか?
Jwan622 2016年

回答:


548

これで問題が解決するかもしれません:

  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のようなファイルでいくつかのサルのパッチを本当に実行したい場合は、手動でそれを必要とする場合があります。

    設定/初期化子/ require.rb

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

PS


1
ので、@ ifyouseewendy-あなたは正確に右だextensions.rbは Railsが命名規則に従っていないして、Railsはロードプロセスでそれを含みません。手動で要求することで機能しました。
Yarin 2013年

@ifyouseewendyモデルをロードする前にファイルを含めるにはどうすればよいですか?パスを追加してそれをオートロードするのはクールですが、インクルードの順序をどのように制御しますか?thx
マトリックス

@Matrix "モデルがロードされる前にファイルを含める"の場合、オートロード機能を使用せずにファイルを手動で要求することができます。
ifyouseewendy 2014年

@ifyouseewendyイニシャライザで必要なのにファイルがautoload_pathにある場合、再ロードされる(2回ロードされる)かどうか?theireはphpのような「require_once」ですか?
マトリックス

5
これは、本番環境のRails 5 APIでは機能しないようです(ただし、開発中は機能します)。使用する必要があると思いますconfig.eager_load_paths << Rails.root.join('lib')。ただし、eager_load_pathsタスクにすべてをロードするという大きな欠点があります。ルラララの方がいいと思います。ここでは、より詳細でブログ記事です:blog.arkency.com/2014/11/...は
hirowatari

33

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

すべて避けるためautoload_pathseager_load_paths手間を、「アプリ」ディレクトリの下に「LIB」または「その他」のディレクトリを作成します。そこに通常行うようにコードを配置すると、Railsはモデルファイルをロード(およびリロード)するのと同じようにファイルをロードします。


3
私はRails 4.2を使用しています。でファイルを自動ロードappしない、手動で実行する必要がある、またはautloadパスに配置する必要がある..
Arup Rakshit

6
あなたは間違っています、Arup、アプリディレクトリのサブディレクトリはすべて、Rails 4.2のautoload_paths配列に自動的にあります。edgeguides.rubyonrails.org /
Dr.Strangelove

app/views追加されないディレクトリを除く。または明示的に削除されます。
ジェームズB.バーン

1
すばらしい答えです。Rails 5 / APIで私のために働いた唯一のもの。
jstafford 2016

6
これは、lib複数のプロジェクトに適用でき、gemに抽出される可能性があるコード用であることを覚えておいてください。そうでない場合は、アプリの検索の下に、services/またはpresenters/これらのサブディレクトリにさらに適切なフォルダを作成します。
PhilT 2016

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

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


1
Rubyで「適切に一致する」とは、ファイルがファイルシステムのLOAD_PATH/module/class.rb(下線付き)にあることを意味します。この場所LOAD_PATHは、Rubyアプリが使用するロードパス(Railsの場合はautoload_paths)にあります。 libRailsによる自動ロードから自動ロードされないように変動し、最近のバージョン(> = Rails 3.x)では自動ロードされません。どんな魔法があなたのためにこの仕事をしているとしても、お勧めできません。おそらくそれは古いRailscastですか?
Peter H.Boling

0

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"

終わり

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.