276

最新の Rails 3 リリースでは lib からモジュールとクラスを自動ロードしなくなったため、それらをロードする最良の方法は何でしょうか?

github から:

A few changes were done in this commit:

Do not autoload code in *lib* for applications (now you need to explicitly 
require them). This makes an application behave closer to an engine 
(code in lib is still autoloaded for plugins);
4

12 に答える 12

252

Rails 2.3.9 の時点で、オートロードするファイルを含むディレクトリを指定できる設定がconfig/application.rbあります。

application.rb から:

# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
于 2010-07-28T19:48:05.970 に答える
200
# Autoload lib/ folder including all subdirectories
config.autoload_paths += Dir["#{config.root}/lib/**/"]

出典:Rails 3クイックヒント:すべてのサブディレクトリを含むlibディレクトリを自動読み込みし、遅延読み込みを回避します

libフォルダーに含まれるファイルは、サーバーの起動時にのみロードされることに注意してください。これらのファイルを快適に自動リロードしたい場合は、以下をお読みください。Rails 3クイックヒント:開発モードでlibフォルダーを自動リロードします。永続的なリロードによりマシンの速度が低下するため、これは実稼働環境向けではないことに注意してください。

于 2010-10-18T18:49:11.823 に答える
84

自動読み込みの魔法

自動ロードが行われるフォルダーを制御するオプションは、他の回答で十分にカバーされていると思います。ただし、必要に応じて自動ロードパスを変更したにもかかわらず、他の誰かが問題をロードしている場合、この回答は、この自動ロードの背後にある魔法が何であるかを説明しようとします。

したがって、サブディレクトリからの読み込みに関しては、知っておくべき落とし穴や規則があります。Ruby/Rails の魔法 (今回は主に Rails) によって、何かが起こっている理由を理解するのが難しくなることがあります。自動ロード パスで宣言されたモジュールは、モジュール名が親ディレクトリ名に対応する場合にのみロードされます。したがって、次のようなものに入れようとする場合lib/my_stuff/bar.rb:

module Foo
  class Bar
  end
end

自動的にロードされることはありません。次に、親ディレクトリの名前を変更してfoo、モジュールを path: にホストするとしますlib/foo/bar.rb。それはあなたのためにそこにあります。別のオプションは、モジュール名でオートロードするファイルに名前を付けることです。明らかに、その名前のファイルは 1 つしか存在できません。自分のものを多くのファイルに分割する必要がある場合は、もちろんその 1 つのファイルを使用して他のファイルを要求することもできますが、開発モードで他のファイルを変更すると、Rails は自動的に変更できないため、お勧めしません。それらをリロードしてください。ただし、本当に必要な場合は、モジュールを使用するために必要な実際のファイルを指定するモジュール名で 1 つのファイルを作成できます。したがって、2 つのファイルを持つことができます。前者は上記lib/my_stuff/bar.rblib/my_stuff/foo.rb同じで、後者は単一行を含みます。require "bar"それはまったく同じように機能します。

PSもう1つ重要なことを追加せざるを得ないと感じています。最近、オートロードする必要のある何かを lib ディレクトリに入れたいと思うときはいつでも、これが実際にこのプロジェクトのために特別に開発しているものである場合 (通常はそうですが、いつの日か多くのプロジェクトやgitサブモジュールなどで使用されるコードの「静的」スニペットに変わります..その場合、間違いなくlibフォルダーにあるはずです)、おそらくその場所はlibフォルダーにまったくありません. app フォルダーの下のサブフォルダーにあるはずです。これが、Rails の新しいやり方だと感じています。明らかに、同じ魔法がオートロード パス内のどこにでも機能しているため、これらの処理に適しています。とにかく、これはこの件に関する私の考えです。同意しないのは自由です。:)


UPDATE: 魔法の種類について..

セヴェリンがコメントで指摘したように、コアの「モジュールの自動ロードメカニズム」は確かにRubyの一部ですが、自動ロードパスのものはそうではありません。Railsは必要ありませんautoload :Foo, File.join(Rails.root, "lib", "my_stuff", "bar"). モジュール Foo を初めて参照しようとすると、モジュールがロードされます。ただし、Rails が行うことは、登録されたフォルダーから自動的に何かを試してロードする方法を提供することです。これは、命名規則について何かを想定する必要があるような方法で実装されています。そのように実装されていない場合、現在ロードされていないものを参照するたびに、すべての autoload フォルダー内のすべてのファイルを調べて、参照しようとしているものが含まれているかどうかを確認する必要があります。これにより、自動ロードと自動再ロードのアイデアが無効になります。ただし、これらの規則が整っていると、モジュール/クラスから、それが定義されている可能性のある場所をロードしようとして、それをロードするだけであると推測できます。

于 2012-03-22T09:59:14.887 に答える
42

警告: 「monkey patch」または「open class」を「lib」フォルダーからロードする場合は、 「autoload」アプローチを使用しないでください!!!

  • " config.autoload_paths " アプローチ: 1 つの場所でのみ定義されたクラスをロードしている場合にのみ機能します。一部のクラスがすでに別の場所で定義されている場合、この方法で再度ロードすることはできません。

  • " config/initializer/load_rb_file.rb " アプローチ: 常に機能します! ターゲット クラスが新しいクラスであっても、既存のクラスの「オープン クラス」または「モンキー パッチ」であっても、常に機能します。

詳細については、https ://stackoverflow.com/a/6797707/445908 を参照してください。

于 2013-01-08T06:52:32.773 に答える
28

非常に似ていますが、これはもう少しエレガントだと思います:

config.autoload_paths += Dir["#{config.root}/lib", "#{config.root}/lib/**/"]
于 2011-10-02T07:46:29.757 に答える
7

私も同じ問題を抱えていました。これが私がそれを解決した方法です。このソリューションは、libディレクトリとすべてのサブディレクトリ(直接だけでなく)をロードします。もちろん、これはすべてのディレクトリに使用できます。

# application.rb
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
于 2010-09-22T15:28:13.670 に答える
5

config.autoload_paths は機能しません。別の方法で解決します

Ruby on rails 3 は、/lib フォルダーからコードを自動リロード (オートロード) しません。中に入れることで解決ApplicationController

Dir["lib/**/*.rb"].each do |path|
  require_dependency path
end 
于 2011-10-18T10:51:44.423 に答える
4

特定のファイルのみが lib のモジュールにアクセスする必要がある場合は、必要なファイルに require ステートメントを追加するだけです。たとえば、1 つのモデルが 1 つのモジュールにアクセスする必要がある場合は、次を追加します。

require 'mymodule'

model.rb ファイルの上部にあります。

于 2010-07-31T01:27:15.607 に答える
2

ファイル名のスペルを正しく入力してください。

真剣に。クラスが Governance::ArchitectureBoard で、ファイルが lib/governance/architecture_baord.rb にあったため (「ボード」で O と A を入れ替えた)、クラスと 1 時間戦いました。

振り返ってみると明らかですが、それを突き止めたのは悪魔でした。Railsがクラス名の変更に基づいてクラスが含まれていると予想するファイルにクラスが定義されていない場合、単にそれを見つけることができません。

于 2017-10-19T16:00:55.430 に答える