17

We're doing an upgrade to Ruby on Rails 3 (like half the world right now), and I've been diligently replacing usages of RAILS_ENV, for example

RAILS_ENV == 'wibble'
# becomes
Rails.env.wibble?

But I'm not as certain of what to do with:

ENV["RAILS_ENV"] ||= 'production'

We've got it at the top of a whole bunch of Rake tasks and daemons, and the idea is that you can pass RAILS_ENV on the command-line, but it defaults to 'production' if it's not passed.

I'm not sure of the new Rails3-appropriate way of doing this. So for now my rails:upgrade:check is complaining mightily of this intrusion of Rails2-ishness...

I don't know if:

::Rails.env ||= 'production'

will work.

Does Rails.env exist in a daemon?

Does it automagickally get pre-populated with the value of RAILS_ENV passed on the command-line or do we need a new way of invoking the daemons?

What is the correct mantra for this?


Update:

Looking into the source-code for Rails.env,

def env
  @_env ||= ActiveSupport::StringInquirer.new(RAILS_ENV)
end

we can deduce a number of things.

Firstly, it looks like RAILS_ENV does actually still exist - which means it can be set and Rails.env will find it...

If Rails is valid in the context of a daemon, then nothing more needs to be done. If not - then I could just not care much and use the old RAILS_ENV as before.

Taryn East
  • 27,486
  • 9
  • 86
  • 108

3 Answers3

11

Rails.env is actually of type ActiveSupport::StringInquirer, which overrides method_missing in order to provide that nice equality syntax. Check: http://api.rubyonrails.org/classes/ActiveSupport/StringInquirer.html

So, if you want to override it to be "production" by defaut, you should write:

Rails.env ||= ActiveSupport::StringInquirer.new('production')

However, you'll have to check which is the uninitialized value of Rails.env, I'm not sure it's really nil.

The best course of action, IMO, is to just prepend env RAILS_ENV=production to all your scripts.

Fábio Batista
  • 25,002
  • 3
  • 56
  • 68
9

Edit lib/tasks/environments.rake

# Sets environments as needed for rake tasks
%w[development production staging].each do |env|
  desc "Runs the following task in the #{env} environment" 
  task env do
    Rails.env = env
  end
end

task :testing do
  Rake::Task["test"].invoke
end

task :dev do
  Rake::Task["development"].invoke
end

task :prod do
  Rake::Task["production"].invoke
end

Source

UPDATE

pass RAILS_ENV=production via command line, something like this:

RAILS_ENV=production rake db:setup

Does this help:

# before
if RAILS_ENV == 'production'
  ...

# Rails 3
if Rails.env.production?
Community
  • 1
  • 1
zengr
  • 38,346
  • 37
  • 130
  • 192
  • ok, scuse my ignorance but: 1) how would you then invoke tasks and 2) how would this affect daemons (which in our case are not invoked via rake). – Taryn East Nov 10 '10 at 13:31
  • Oh... and just o be through: 3) how does this solution match our requirement to "default to production if nothing is passed on the command-line, but otherwise allow us to override it if we do pass something on the command line" ? – Taryn East Nov 10 '10 at 13:33
  • Hiya - yes, this explains how to use rake tasks... but what about our daemons? – Taryn East Nov 11 '10 at 17:45
  • Ok, looking deeper into the posts from which you've taken this code - I have to say it probably isn't appropriate for me at all. The environment.rake code you've borrowed - is from somebody's custom rake environments. It *only* covers setting the environment for rake tasks. – Taryn East Nov 13 '10 at 12:32
  • The second bit of code you've provided - comes directly from the docs which I have already used. As I specified - I have already updated our code to use Rails.env instead of RAILS_ENV in all our usual code. – Taryn East Nov 13 '10 at 12:33
  • The questions that remain outstanding are the main ones I ask in this post: Our daemons are initiated by cron - not rake, so rake is not relevant to this case. So: can you use Rails.env in a daemon? if so, can you pass RAILS_ENV on the command-line and have it set Rails.env? if so - how? – Taryn East Nov 13 '10 at 12:36
  • by daemons you mean cron jobs? Does this help: http://wiki.joyent.com/smartmachine%3arails%3acron ? – zengr Nov 16 '10 at 02:41
2
if Rails.env.production?
  puts '...'
Quanyi Ma
  • 145
  • 1
  • 5
  • 2
    I'm afraid you misunderstand the requirements. I don't want to know whether or not I am in the production environment. I want to force my scripts to run in the production environment by default. – Taryn East Mar 22 '11 at 15:04