6

我想用初始化程序预填充我的缓存,但我不需要每次运行rake或运行时都运行此代码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

更新:

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

仍然想知道是否可以按照我上面尝试的方式进行。

4

1 回答 1

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

兴趣点在上面编号。也就是说,此时#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中,您有更多希望!在加载应用程序环境时,生成器命名空间已经加载。这意味着在初始化程序中,您可以执行以下操作:

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 回答