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

爷,独闯天下 提交于 2019-11-28 21:11:18

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'

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
donV

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

'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

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".

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.

avillagran

For Padrino:

Console check:

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

Server Check:

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