How to determine if Rails is running from CLI, console or as server?

倖福魔咒の 提交于 2019-11-27 12:48:52

问题


I have a middleware for announcing my application on the local network app using Bonjour, but it's also announcing the service when Rails is invoked from rake or through the console.

I'd like to exclude these cases, and only use the Bonjour middleware when Rails is running as a server.

The middleware configuration accepts a proc to exclude middlewares under certain conditions using a proc:

config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env| 
  env['HTTPS'] != 'on' 
}

But how do I determine if Rails was invoked from the CLI, console or as a server?


回答1:


Peeking at the Rails module using pry reveals that console invocations can be detected like this:

Rails.const_defined? 'Console'

And server invocations like this:

Rails.const_defined? 'Server'



回答2:


Super helpful. Thanks @crishoj.

I wanted to examine the Console object more closely for another problem I am working on and found out that the Console constant can be reached with Rails::Console, so another option for checking would be to use:

defined? Rails::Console
defined? Rails::Server



回答3:


Using Rails 5 with or without an app-server like Puma/Passenger, here are three ways to determine how your app is running:

# 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'}}



回答4:


'Server' isn't defined when Rails 5 runs under Passenger.

The best solution I've found is a variant of this answer:

if %w(rails rake).include?(File.basename($0))
   <console or runner>
else
   <server>       
end



回答5:


Summary of the environment for each command.

I found the existing answers to be either incomplete, redundant or not exhaustive. So here is a table format of each command and what the resulting environment looks like.

Rails 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                              |  []                             |

You can see that just checking for "Server" being defined as a Rails constant will not catch generators, like rails g migration. You need to check the ARGV to do that.

I hope this helps. I only had immediate access to Rails 4.2 but feel free to add sections for other Rails versions, as well as add any additional commands that need "catching".




回答6:


In our project I had to detect console mode in boot.rb, for that I used:

in_console = (ARGV & ['c', 'console']).any?

Not a fool-proof solution, but good enough for our use case.




回答7:


For Padrino:

Console check:

if Padrino::constants.include? :Cli
    #your code
end

Server Check:

if !Padrino::constants.include? :Cli
    #your code
end


来源:https://stackoverflow.com/questions/13506690/how-to-determine-if-rails-is-running-from-cli-console-or-as-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!