Environments in Rails 0.13.1
Posted by kev Tue, 06 Sep 2005 00:30:00 GMT
Development, test and production: we all know and love the default rails environments that let us seperate our databases and tests. What do they do, how do they work, and how can we further customize our rails environment?
Please note: As of changeset 2115 the rails environment does not work like this article describes. This article will cover environments in 0.13.1 and earlier. I will release another article this week explaining the new environment system.
Environments 101
So the first place we can look for information on environments is config/environment.rb. If you have added external libraries to your rails app or turned an app into production mode, should should be mildly familiar with this file. It does things like set your root rails directory, organize load paths and set your working environment.
Allow me to direct you to the lines of code significant to our discussion.
# See config/environments/*.rb for environment-specific configuration.
RAILS_ENV = ENV['RAILS_ENV'] || 'development'
...
# Load the Rails framework. Mock classes for testing come first.
ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"]
...
# Environment-specific configuration.
require_dependency "environments/#{RAILS_ENV}"
...
# Configure defaults if the included environment did not.
begin
RAILS_DEFAULT_LOGGER = Logger.new("#{RAILS_ROOT}/log/#{RAILS_ENV}.log")
RAILS_DEFAULT_LOGGER.level = (RAILS_ENV == 'production' ? Logger::INFO : Logger::DEBUG)
rescue StandardError
...
endThis is alot to look at, so lets take it one snippet at a time.
# See config/environments/*.rb for environment-specific configuration.
RAILS_ENV = ENV['RAILS_ENV'] || 'development'This is the line you’re most likely to be familiar with because it sets the current working environment. If you specify an environment in the shell it will use that, or default to developement.
# Load the Rails framework. Mock classes for testing come first.
ADDITIONAL_LOAD_PATHS = ["#{RAILS_ROOT}/test/mocks/#{RAILS_ENV}"]
...
# Environment-specific configuration.
require_dependency "environments/#{RAILS_ENV}"These lines load environment specific information. The first loads mock classes use primarily for testing and the second loads a configuration file.
Digging Deeper
We’ve seen how environment.rb decides what configuration will be used, but lets look at what happens in those configuration files.
# Log error messages when you accidentally call methods on nil.
require 'active_support/whiny_nil'
# Reload code; show full error reports; disable caching.
Dependencies.mechanism = :load
ActionController::Base.consider_all_requests_local = true
ActionController::Base.perform_caching = false
# The breakpoint server port that script/breakpointer connects to.
BREAKPOINT_SERVER_PORT = 42531The comments in the file cover what it does, but note that this is where all the development mode goodness is controlled. Here its determined that we’re alway going to load our dependencies, that we get full error reports (because we treat the user as a local user) and we won’t do caching. Thats it!
# Log error messages when you accidentally call methods on nil.
require 'active_support/whiny_nil'
# Don't reload code; show full error reports; disable caching.
Dependencies.mechanism = :require
ActionController::Base.consider_all_requests_local = true
ActionController::Base.perform_caching = false
# Tell ActionMailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
ActionMailer::Base.delivery_method = :testAgain, this file is very well commented, but you can see that for running tests we only run load the code once and an extra line ActionMailer::Base.delivery_method = :test appears. This line configures our ActionMailer (if we’re using one) to only pretend to send email so they don’t get set off in one of our (hopefully) many test cases.
# Don't reload code; don't show full error reports; enable caching.
Dependencies.mechanism = :require
ActionController::Base.consider_all_requests_local = false
ActionController::Base.perform_caching = trueMostly boring this time, requrie dependencies once, don’t spit out full error messages and do caching.
So, I want to make my own evironment
Lets say for the sake of demonstration that you want to create some sort of uber-development environment where it doesn’t send off email and allows caching, but still does full error messages and connects to the non-production database. Rails makes this simple.
Step 1. Update config/database.yml
In uber-development mode we want to use the same database as regular, wimpy development, so we add the following lines to config/database.yml
uber-development:
developmentNext, we create a uber-development specific file in config/environments called uber-development.rb.
# Log error messages when you accidentally call methods on nil.
require 'active_support/whiny_nil'
# Reload code; show full error reports; disable caching.
Dependencies.mechanism = :load
ActionController::Base.consider_all_requests_local = true
# Uber-development can deal with caching!
ActionController::Base.perform_caching = true
# Uber-development need not send email
ActionMailer::Base.delivery_method = :test
# The breakpoint server port that script/breakpointer connects to.
BREAKPOINT_SERVER_PORT = 42531Finally we modify environment.rb to use our new, sassy development environment.
#RAILS_ENV = ENV['RAILS_ENV'] || 'development'
RAILS_ENV = 'uber-development'So now, if we run script/server we can see the effect of our changes, and trust the configuration is what we wanted.
[Dionysus:~/web/ellipses] kevincla% script/server
=> Rails application started on http://0.0.0.0:3000
=> Ctrl-C to shutdown server; call with --help for options
[2005-09-05 13:45:33] INFO WEBrick 1.3.1
[2005-09-05 13:45:33] INFO ruby 1.8.2 (2004-12-25) [powerpc-darwin7.8.0]
[2005-09-05 13:45:33] INFO WEBrick::HTTPServer#start: pid=10640 port=3000
^C[2005-09-05 13:45:40] INFO going to shutdown ...
[2005-09-05 13:45:40] INFO WEBrick::HTTPServer#start done.
[Dionysus:~/web/ellipses] kevincla% cd log/
[Dionysus:~/web/ellipses/log] kevincla% ls
development.log test.log uber-development.log
[Dionysus:~/web/ellipses/log] kevincla% cat uber-development.log
# Logfile created on Mon Sep 05 13:45:32 PDT 2005 by logger.rb/1.5.2.4So we -are- using the new environment. Good stuff. For explanations of the new environment code in edgerails and probably 1.0, keep watch here.

