6

MongoMapperモデルを定義するプラグインを作成しようとしています。問題は、実行するscript/consoleと次のエラーが発生することです。

/home/helder/.rvm/gems/ruby-1.8.7-p249/gems/mongo_mapper-0.8.2/lib/mongo_mapper/connection.rb:29:in `` database':NameError:MongoMapper::Connection`の初期化されていないクラス変数@@database_name

これにより、データベース接続を設定する前に、プラグインモデルを読み込もうとしていると思います。残りのアプリケーションコードのに​​プラグインをロードするにはどうすればよいですか?

4

1 に答える 1

11

私は、私が遭遇したエラーと、タイトルに記載されている一般的な質問の両方に対処しようとします。

特定のエラー

私は問題が何であるかを理解しました。上記のコメントで述べたように、問題は、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.rblib/app/modelsrequire

一般的な質問

初期化コードのに​​Railsにプラグインをロードさせる方法は?

プラグインで、このブロック内で待機する必要があるものinit.rbをすべてスローします。

config.after_initialize do
  # require my models
  # do this
  # do that
end

その変数は、ファイル内にconfig渡されるブロックに渡されるものと同じであり、追加費用なしでRailsによってプラグインで使用できるようになります。Rails::Initializer.runconfig/environment.rbinit.rb

そのブロック内に置いたものはすべて、すべてのロードと初期化が完了した後、リクエストが届く前に(によってRails::Initializer#after_initialize)実行されます。お楽しみください。

于 2010-07-13T01:29:10.567 に答える