如何在运行`rails generate`时阻止初始化程序运行

jor*_*npg 6 initialization ruby-on-rails-3

我想预填充我的缓存与初始化,但我不需要这个代码运行每次运行时rake或rails g等耙捆扎机很容易对付,但类似的解决方案没有为发电机工作:

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

这必须是因为rails/generators(或类似的东西)require在运行时编辑.如何查看正在运行的命令是否正确rails g xyz?

更新:

这里可以找到两个解决方案: Rails 3初始化程序只能在`rails server`上运行而不是`rails generate`等

仍然想知道我是否有可能以我上面尝试过的方式.

Gav*_*ler 1

在Rails 3中,您想要做的事情是可以想象的,但是是以一种 hacky 的方式。就是这样:

当您拨打rails generate电话时,呼叫路径如下所示:

在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
Run Code Online (Sandbox Code Playgroud)

兴趣点已在上面编号。也就是说,此时#1您正在运行的命令正在从ARGV. 在您的情况下,这意味着generate将从命令行参数中删除。

此时#2您的环境已加载,此时您的初始化程序将被执行。这里是困难的部分 - 因为没有任何指示此时已加载特定命令(这发生在#3),没有信息可以确定生成器正在运行!

让我们插入一个脚本来config/initializer/debug.rb看看运行后有什么可用rails generate model meep:

puts $0     #=> "script/rails"
puts ARGV   #=> ["model", "meep"]
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,没有发电机正在运行的直接信息。也就是说,存在间接信息。即ARGV[0] #=> "model"。可以想象,您可以创建一个可能的生成器列表,并检查该生成器是否已被调用ARGV[0]。我负责任的开发人员说这是一种黑客行为,可能会以您意想不到的方式破坏,所以我会谨慎使用它。

唯一的其他选择是script/rails按照您的建议进行修改——这并不是一个太糟糕的解决方案,但当您升级到 Rails 4 时可能会崩溃。


在Rails 4中,您有更多希望!当加载应用程序环境时,生成器命名空间已经加载。这意味着在初始化程序中您可以执行以下操作:

if defined? Rails::Generators   #=> "constant"
  # code to run if generators loaded
else
  # code to run if generators not loaded
end
Run Code Online (Sandbox Code Playgroud)