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

时间:2012-11-13 00:04:18

标签: ruby-on-rails-3 initialization

我想使用初始化程序预填充缓存,但每次运行rakerails 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

更新

可在此处找到两种解决方案:Rails 3 initializers that run only on `rails server` and not `rails generate`, etc

仍然想知道我是否有可能以上述方式尝试过。

1 个答案:

答案 0 :(得分:1)

Rails 3 中,您可能会想到的是,但是以一种黑客的方式。以下是:

当您进行rails generate调用时,调用路径如下所示:

rails/commands内为generate生成的代码:

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。在您的情况下,将从命令行args中删除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 中,您获得了更多希望!到application environment is being loaded时,已经加载了generator命名空间。这意味着在初始化程序中,您可以执行以下操作:

if defined? Rails::Generators   #=> "constant"
  # code to run if generators loaded
else
  # code to run if generators not loaded
end