ruby-on-rails-3 – 运行`rails generate`时如何防止初始化程序运行

我想用初始化程序预填充我的缓存,但是每次运行rake或rails g等时都不需要运行此代码.Rake和Bundler很容易处理,但类似的解决方案对于生成器不起作用:

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

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

更新:

这里有两种解决方案:Rails 3 initializers that run only on `rails server` and not `rails generate`, etc

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

最佳答案
在Rails 3中,你想要做的事情是可能的,但是以一种黑客的方式.这是如何做:

当您生成rails生成调用时,调用路径如下所示:

调用> bin/rails,最终将您路由到execute script/rails
> script/rails执行,需要rails/commands
> rails/commands已加载,这是主要关注点.

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.在您的情况下,意味着生成将从命令行args中删除.

在#2点,您的环境会被加载,此时您的初始化程序将被执行.这是一个棘手的部分 – 因为此时没有任何指示特定命令的信息(这发生在#3),没有信息可以确定正在运行的发电机!

让我们在config / initializer / debug.rb中插入一个脚本,看看当我们运行rails generate model meep时可用的内容:

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

如您所见,没有直接信息表明正在运行生成器.也就是说,有间接信息.即ARGV [0]#=> “模型”.可以想象,您可以创建一个可能的生成器列表,并检查是否已在ARGV [0]上调用该生成器.我这个负责任的开发人员说这是一个黑客,可能会以你不会想到的方式打破,所以我会小心翼翼地使用它.

唯一的另一个选择是像你建议的那样修改脚本/ rails – 这不是一个解决方案,但是当你升级到Rails 4时可能会破坏.

在Rails 4中,你有更多的希望!到application environment is being loaded时,生成器命名空间已经加载.这意味着在初始化程序中,您可以执行以下操作:

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

转载注明原文:ruby-on-rails-3 – 运行`rails generate`时如何防止初始化程序运行 - 代码日志