6

rakeキャッシュにイニシャライザを事前設定したいのですが、 orなどを実行するたびにこのコードを実行する必要はありませんrails g。Rake と Bundler は簡単に処理できますが、同様のソリューションはジェネレータでは機能しません。

# config/initializers/prepop_cache.rb
if !defined?(::Bundler) and !defined?(::Rake) and !defined(Rails::Generators)
  # do stuff
end

これは、実行時にrails/generators(または同様のものが)require編集されるためであるに違いありません。実行中のコマンドが であるかどうかを確認するにはどうすればよいrails g xyzですか?

アップデート:

ここで 2 つの解決策を見つけることができます

上記で試した方法でそれが可能かどうかを知りたいです。

4

1 に答える 1

1

Rails 3では、あなたがしようとしていることはおそらく可能ですが、ハックな方法です。方法は次のとおりです。

電話をrails generateかけると、callpath は次のようになります。

rails/commands内で生成するために実行されるコード:

ARGV << '--help' if ARGV.empty?

aliases = {
  "g"  => "generate",
  "c"  => "console",
  "s"  => "server",
  "db" => "dbconsole"
}

command = ARGV.shift                       # <= #1
command = aliases[command] || command

case command
when 'generate', 'destroy', 'plugin', 'benchmarker', 'profiler'
  require APP_PATH
  Rails.application.require_environment!   # <= #2
  require "rails/commands/#{command}"      # <= #3

興味のあるポイントは上に番号が付けられています。つまり、#1実行中のコマンドがオフにシフトしていることARGV。あなたの場合、これgenerateはコマンドライン引数から削除されることを意味します。

#2環境がロードされる時点で、イニシャライザが実行されます。そして、ここが難しい部分です。この時点で特定のコマンドがロードされたことを示すものは何もないため (これは で発生します#3)、ジェネレーターが実行されていることを判断する情報はありません!

にスクリプトを挿入して、config/initializer/debug.rb実行した場合に何が利用できるかを見てみましょうrails generate model meep:

puts $0     #=> "script/rails"
puts ARGV   #=> ["model", "meep"]

ご覧のとおり、ジェネレーターが実行されているという直接的な情報はありません。つまり、間接的な情報があります。つまりARGV[0] #=> "model"。おそらく、可能なジェネレーターのリストを作成し、そのジェネレーターが で呼び出されているかどうかを確認できますARGV[0]。私の責任ある開発者は、これはハックであり、予期しない方法で壊れる可能性があるため、慎重に使用すると述べています。

他の唯一のオプションは、script/railsあなたが提案したように変更することです-これはそれほど悪い解決策ではありませんが、Rails 4にアップグレードすると壊れる可能性があります.


Rails 4では、より多くの希望があります! アプリケーション環境が読み込まれるまでに、generators 名前空間は既に読み込まれています。これは、イニシャライザで次のことができることを意味します。

if defined? Rails::Generators   #=> "constant"
  # code to run if generators loaded
else
  # code to run if generators not loaded
end
于 2015-09-25T19:18:21.417 に答える