43

I have this code in an initializer:

if $0 == 'irb'
  # ...
end

It works fine with Rails 2.3 but in Rails 3 the value of $0 is 'script/rails' no matter if it was started with rails c or rails s. ARGV is an empty array. How can I detect if the application has been started with "rails c" or "rails console"?

Markus
  • 735
  • 6
  • 8

2 Answers2

83

You could try this perhaps

if defined?(Rails::Console)
  # in Rails Console
else
  # Not in Rails Console
end
Aditya Sanghi
  • 13,370
  • 2
  • 44
  • 50
  • 9
    Note that this won't work during Rails initialization when running Spring. – Jonathan Swartz Sep 30 '14 at 00:19
  • 3
    You want `Rails.const_defined?("Console")`, not `defined?(Rails::Console)`. – wxgeorge Jan 16 '17 at 03:58
  • @wxgeorge why is that better? – Andreas Storvik Strauman Feb 24 '17 at 17:48
  • 1
    @AndreasStorvikStrauman `Rails::Console` is not defined in all contexts and configurations. When it's not, you'll get a `NameError`. `Rails.const_defined?("Console")` is safe so long as `Rails` is defined. – wxgeorge Feb 25 '17 at 01:30
  • 4
    @wxgeorge @Andreas `defined?` is a special method and will let you pass whatever name you want, e.g. `defined?(Hwddddw::Ewedw) # => nil` – Dorian Feb 27 '17 at 18:53
  • @Dorian - whoa my bad! Apologies. I got an error when I first used Aditya's original formulation, and assumed it was as I reported above. Thanks for the correction. – wxgeorge Feb 27 '17 at 23:32
  • unless i'm missing something, this is not working anymore in rails 6. https://stackoverflow.com/a/57526113/293974 *is* working. – Hertzel Guinness Jun 28 '20 at 19:35
8

Many years later there is a better method to do this registering blocks to run for the console (using the railtie interface).

So in the initializer you can write:

Rails.application.console do
  # your code here
end

The good think about this is that it also works for runner and it should also work with spring (but I didn't test that).

eloyesp
  • 3,135
  • 1
  • 32
  • 47