如何确定Rails是从CLI,控制台还是作为服务器运行?

cri*_*hoj 29 rack ruby-on-rails rack-middleware

我有一个中间件,用于使用Bonjour在本地网络应用程序上宣布我的应用程序,但是当从rake或通过控制台调用Rails时,它也会宣布该服务.

我想排除这些情况,并且只在Rails作为服务器运行时使用Bonjour中间件.

中间件配置接受proc以在某些条件下使用以下内容排除中间件proc:

config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env| 
  env['HTTPS'] != 'on' 
}
Run Code Online (Sandbox Code Playgroud)

但是,如何确定是从CLI,控制台还是作为服务器调用Rails?

cri*_*hoj 41

在窥测Rails使用模块表明控制台调用可以这样检测:

Rails.const_defined? 'Console'
Run Code Online (Sandbox Code Playgroud)

像这样的服务器调用:

Rails.const_defined? 'Server'
Run Code Online (Sandbox Code Playgroud)

  • 有趣的是,这只有在调用命令"rails s"或"rails c"时才有效.如果您通过不同的命令(例如,"unicorn_rails")运行服务器,则永远不会定义这些常量.Rails :: Server看起来像是命令解析过程的一部分,即使它继承自:: Rack :: Server. (4认同)
  • 即使使用 rails c,这对 Rails 4 也不起作用。我在控制台中定义了服务器和控制台。 (2认同)

Nat*_*nna 15

超级有帮助.谢谢@crishoj.

我想更仔细地检查Console对象以解决我正在处理的另一个问题,并发现可以使用Console常量Rails::Console,因此检查的另一个选项是使用:

defined? Rails::Console
defined? Rails::Server
Run Code Online (Sandbox Code Playgroud)


don*_*onV 9

在有或没有Puma / Passenger之类的应用服务器的情况下使用Rails 5,可以通过以下三种方法确定应用程序的运行方式:

# We are running in a CLI console
defined?(Rails::Console)

# We are running as a Rack application (including Rails)
caller.any?{|l| l =~ %r{/config.ru/}}

# We are running as a CLI console
caller.any?{|l| l =~ %r{/lib/rake/task.rb:\d+:in `execute'}}
Run Code Online (Sandbox Code Playgroud)


Jos*_*ter 7

每个命令的环境摘要。

我发现现有的答案要么不完整,要么多余,要么不够详尽。所以这里是每个命令的表格格式以及结果环境的样子。

导轨 4.2

| Command                            |  Rails.const_defined?( "Console" )  |  Rails.const_defined?( "Server" )  |               ARGV              |
|------------------------------------|-------------------------------------|------------------------------------|---------------------------------|
| `rake db:migrate:status`           |  false                              |  true                              |  ["db:migrate:status"]          |
| `rails console`                    |  true                               |  true                              |  []                             |
| `rails server`                     |  false                              |  true                              |  []                             |
| `rails g migration new_migration`  |  false                              |  true                              |  ["migration", "new_migration"] |
| `rails r "puts 'Hi'"`              |  false                              |  true                              |  []                             |
Run Code Online (Sandbox Code Playgroud)

您可以看到,仅检查定义为Rails常量的“服务器”不会捕获生成器,例如rails g migration. 你需要检查ARGV来做到这一点。

我希望这有帮助。我只能立即访问 Rails 4.2,但可以随意添加其他 Rails 版本的部分,以及添加任何需要“捕获”的其他命令。