16

I am trying to create a rails application that assigns one value to a variable when the environment is the development environment, and another value to that same variable when the environment is the production environment. I want to specify both values in my code (hardwired), and have rails know which value to assign to the variable based on which environment is running. How do I do this?

In case it is important, I later access that variable and return its value in a class method of a model.

Morris Singer
  • 1,715
  • 2
  • 18
  • 34

4 Answers4

25

You can do this with initializers.

# config/initializers/configuration.rb
class Configuration
  class << self
    attr_accessor :json_url
  end
end

# config/environments/development.rb
#  Put this inside the ______::Application.configure do block
config.after_initialize do
  Configuration.json_url = 'http://test.domain.com'
end

# config/environments/production.rb
#  Put this inside the ______::Application.configure do block
config.after_initialize do
  Configuration.json_url = 'http://www.domain.com'
end

Then in your application, call the variable Configuration.json_url

# app/controller/listings_controller.rb
def grab_json
  json_path = "#{Configuration.json_url}/path/to/json"
end

When you're running in development mode, this will hit the http://test.domain.com URL.

When you're running in production mode, this will hit the http://www.domain.com URL.

Jason Noble
  • 3,756
  • 19
  • 21
  • 1
    Any chance this is broken in 3.1? Worked like a charm in my 3.0 app, now getting NoMethodError (undefined method 'test_conf' for ActiveSupport::Configurable::Configuration:Class): – Josh Diehl Sep 15 '11 at 04:03
  • # config/application.rb class Application < Rails::Application attr_accessor :json_url – lnguyen55 Sep 24 '11 at 09:32
  • 8
    There is a much better way to do this with Rails 3+. You can use the existing config to create config.json_url = '...' I explained it further on http://jasonnoble.org/2011/12/updated-rails3-custom-environment-variables.html – Jason Noble Dec 04 '11 at 03:21
  • This can be more easily managed by doing it with a .yml file http://stackoverflow.com/questions/11648620/setting-environment-variables-in-rails-3-devise-omniauth – Ash Blue Jan 14 '13 at 05:04
15

I like to store settings in YAML. To have different settings based on the environment, with defaults, you can have an initializer file (say config/initializers/application_config.rb) like this:

APP_CONFIG = YAML.load_file("#{Rails.root}/config/application_config.yml")[Rails.env]

…and then in config/application_config.yml :

defaults: &defaults
    my_setting: "foobar"

development:
    # add stuff here to override defaults.
    <<: *defaults

test:
    <<: *defaults

production:
    # add stuff here to override defaults.
    <<: *defaults

…then, pull out the settings with APP_CONFIG[:my_setting]

Ned Baldessin
  • 151
  • 1
  • 2
  • 2
    How can you then use the "APP_CONFIG" in the code? I get an error : uninitialized constant MyController::APP_CONFIG – Jojje Jun 21 '12 at 19:47
  • @Jojje, restart application. See dedicated railscast if you have any further questions http://railscasts.com/episodes/85-yaml-configuration-file. Also symbol keys doesn't work for me. `APP_CONFIG['my_setting']` — this is how you read setting. – jibiel Oct 13 '12 at 12:07
  • 1
    I needed this config in other initializers, so I ended up using the `YAML.load_file(...)` line within `config/environment.rb`, just before the `Application.initialize!` line. (via [Tyler Long](http://stackoverflow.com/a/11054390/361609)) – colllin Jan 24 '13 at 05:12
3

I use the Yettings gem in Rails 3.2, which allows me to store my application variables in config/yettings.yml like so:

defaults: &defaults
  api_key: asdf12345lkj
  some_number: 999
  an_erb_yetting: <%= "erb stuff works" %>
  some_array:
    - element1
    - element2

development:
  <<: *defaults
  api_key: api key for dev

test:
  <<: *defaults

production:
  <<: *defaults

And access them like this:

#/your_rails_app/config/yetting.yml in production
Yetting.some_number #=> 999
Yetting.api_key #=> "asdf12345lkj"
manafire
  • 5,984
  • 4
  • 43
  • 53
-2

You can find out the environment like this:

ruby-1.9.2-p0 > Rails.env
  => "development"

Store the value in a global variable in your config/application.rb for example:

$foo = "something"

You could also assign the variable in your config/environments/ files instead of deciding based ond Rails.env in application.rb. Depends on your situation.

Lennart Koopmann
  • 826
  • 1
  • 8
  • 14