私は、私が遭遇したエラーと、タイトルに記載されている一般的な質問の両方に対処しようとします。
特定のエラー
私は問題が何であるかを理解しました。上記のコメントで述べたように、問題は、Rails(2.3.8)がActiveRecordを使用する場合、最初にデータベース接続をセットアップし、次にgemをロードし、次にプラグインを(この順序で)ロードすることです。したがって、初期化中にデータベースにアクセスする必要のあるプラグインがある場合(つまり、プラグインinit.rb
またはこれによって作成された他のファイル内require
)、すべてが正常に機能します。
ただし、MongoMapperを使用する場合、RailsはMongoMapperのクラスを他のすべてのgem /プラグインと一緒にロードしますが、接続をセットアップしません(Railsはそれを行わず、プラグインもそれ自体をトリガーしません)。MongoDBのドキュメントで現在推奨されている方法は、次のような初期化子を作成することです。
MongoMapper.connection = Mongo::Connection.new('localhost', 27017)
MongoMapper.database = "#myapp-#{Rails.env}"
if defined?(PhusionPassenger)
PhusionPassenger.on_event(:starting_worker_process) do |forked|
MongoMapper.connection.connect_to_master if forked
end
end
ただし、プラグインはファイルが実行される前にconfig/initializers
初期化されるため、MongoMapperモデルを定義しようとすると、データベースにアクセスする呼び出し(key
クラスメソッドの呼び出しなど)に到達するとすぐに、BOOMになります。質問で引用されたエラーが表示されます。
これを解決する1つの方法は、データベースを必要とするファイルを必要とせず、ロードパスに追加するだけです(またはにない場合は、 Railsが自動的にロードパスに追加します)。そうすれば、モデルは、参照されるときにRailsの自動クラスローダーによってのみdされます。これは通常、アプリケーションコード内にあります。それまでに、db接続はすでに設定されています。もちろん、これは、プラグインの初期化中にこれらのクラスを実際に参照する必要がない場合にのみ機能します。それ以外の場合は、読み進めてください。init.rb
lib/
app/models
require
一般的な質問
初期化コードの後にRailsにプラグインをロードさせる方法は?
プラグインで、このブロック内で待機する必要があるものinit.rb
をすべてスローします。
config.after_initialize do
# require my models
# do this
# do that
end
その変数は、ファイル内にconfig
渡されるブロックに渡されるものと同じであり、追加費用なしでRailsによってプラグインで使用できるようになります。Rails::Initializer.run
config/environment.rb
init.rb
そのブロック内に置いたものはすべて、すべてのロードと初期化が完了した後、リクエストが届く前に(によってRails::Initializer#after_initialize
)実行されます。お楽しみください。