360

I was wondering how to add custom configuration variables to a Rails application and how to access them in the controller?

Secondly, I was planning to have S3 support for uploads in my application, if I wanted to add a yaml file with the S3 access, secret key, how do I initialize it in my Rails App and how do I access the values that I have defined in that config file.

BinaryButterfly
  • 18,137
  • 13
  • 50
  • 91
Shiv
  • 8,362
  • 5
  • 29
  • 32
  • 1
    Duplicate: http://stackoverflow.com/questions/592554/best-way-to-create-custom-config-options-for-my-rails-app – John Topley Sep 20 '09 at 09:24
  • Slightly related: Don't forget to restart the server when adding new configuration variables. – Damien Sep 30 '15 at 07:41

15 Answers15

386

In Rails 3, Application specific custom configuration data can be placed in the application configuration object. The configuration can be assigned in the initialization files or the environment files -- say for a given application MyApp:

MyApp::Application.config.custom_config_variable = :my_config_setting

or

Rails.configuration.custom_config_variable = :my_config_setting

To read the setting, simply call the configuration variable without setting it:

Rails.configuration.custom_config_variable
=> :my_config_setting

UPDATE Rails 4

In Rails 4 there a new way for this => http://guides.rubyonrails.org/configuring.html#custom-configuration

enter image description here

Joel AZEMAR
  • 2,506
  • 25
  • 31
Jack Pratt
  • 3,877
  • 2
  • 14
  • 2
  • This doesn't seem to actually work. I'm unable to reference the variable anywhere else in the application. There's also no mention of being able to do it this way here: http://guides.rubyonrails.org/configuring.html – BeepDog Mar 09 '11 at 20:55
  • 11
    It works for me. I put my environment specific configuration settings in environments/{environment}.rb, e.g., environments/development.rb. Make sure you restart your server after modifying. There may be more elegant techniques, but I'm upgrading an existing app which previously used ENV['XXX'] in the same file, and since I want to limit the amount of refactoring during the upgrade, this worked out well. – pduey Apr 26 '11 at 16:13
  • 13
    This is assignment but how do you access this value then? – kevzettler Aug 10 '11 at 16:39
  • 10
    If you look in the application.rb of a rails 3.x app it sais "Application configuration should go into files in config/initializers" as per this answer. There is plenty of documentation on how to access the variable (http://edgeguides.rubyonrails.org/configuring.html). e.g. in a file called some_variables.rb in the initializers folder place the variable as described above (replacing MyApp with the name of your app) then when you want to use it just call config.custom_config_variable You can of course use whatever variable name you like. @Jack Pratt you could edit a more complete answer? – jamesc Aug 31 '11 at 14:58
  • 1
    I'm on Rails 3.0.4 and could access the config variable only by doing: Rails.application.config.custom_config_variable. – Amin Ariana Dec 18 '11 at 23:42
  • 48
    Dude, simple: Path: `config/environments/production.rb` Config: `config.whatever = false` Access it anywhere: `Rails.configuration.whatever` – Victor S Jan 01 '12 at 23:26
  • Is it possible to use this to set different values in different environments? I want to configure a variable that has different values in dev and prod. – Stewart Johnson Jan 11 '12 at 05:10
  • 5
    Beware that if you set something only in production, and try to access it in another environment, it would complain `undefined method`. – lulalala Mar 15 '12 at 10:44
  • 1
    What so cool about this bulky solution? A couple of people will die on Earth while you type `Rails.configuration.whatever`. Besides, it's not suitable when you need to keep **sensitive data**, e.g. an app email password, _out_ of the **scm**. – jibiel Oct 13 '12 at 12:49
  • Yeah as @lulalala has mentioned, it gives an error if the value isn't defined. I want to assume a value if it isn't defined... is this possible? – msanjay Dec 13 '12 at 21:32
  • Is there a way to check if a config name has been defined? i.e. if `Rails.configuration.custom_config_variable` is conditionally set, and then later it is used, but get `undefined method`. – Ian Vaughan Jan 02 '13 at 15:55
  • 1
    @msanjay, try `Rails.config.my_variable ||= 'default value'`. That overrides the variable with 'default value' if it's not defined, but leaves it alone otherwise. – Nick McCurdy Jan 06 '13 at 20:33
  • 1
    this does not work for me on rails 3.2.11, i get a 'rails could not start: undefined method error' in the `development.rb` config file, makes sense as I am trying to write to a field that does not exist! how could this ever work? – lynks Jan 30 '13 at 16:15
  • @Tilo, lynks: Use this answer for > Rails 3.2: http://stackoverflow.com/questions/4800028/rails-3-setting-custom-environment-variables – Besi Mar 11 '13 at 19:46
  • This may be more of the ruby question. How MyApp::Application.config.custom_config_variable work. I don't think there is a custom_config_variable setter or getter in the config(Rails::Application::Configuration) object. How does this work from ruby perspective object point of view ?. – Srikan Nov 02 '13 at 05:39
  • This is not working in Rails 4.1 I get errors "...`method_missing': undefined method `store' for #..." if I try to add a variable like config.store.works – Spundun Mar 19 '14 at 21:54
  • 3
    @Spundun I had the same problem, this will do the trick: http://stackoverflow.com/a/18768914/498238 – Sonata Apr 22 '15 at 10:59
  • 2
    Note that `x` part is probably there for namespacing and *must be* included when entering custom config. It's an object of type [`Rails::Application::Configuration::Custom`](https://github.com/rails/rails/blob/v4.2.1/railties/lib/rails/application/configuration.rb#L191). – Halil Özgür Jun 15 '15 at 17:22
  • As @HalilÖzgür pointed out, `x` is for namespacing, so it could assign a custom config object. Otherwise it will just to be method missing, then dynamically create attributes, which could be bad. – Dingle Sep 18 '15 at 05:23
172

Update 1

Very recommended: I'm going with Rails Config gem nowadays for the fine grained control it provides.

Update2

If you want a quick solution, then check Jack Pratt's answer below.

Although my original answer below still works, this answer is now outdated. I recommend looking at updates 1 and 2.

Original Answer:

For a quick solution, watching the "YAML Configuration File" screen cast by Ryan Bates should be very helpful.

In summary:

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

# application.rb
if APP_CONFIG['perform_authentication']
  # Do stuff
end
Community
  • 1
  • 1
khelll
  • 23,590
  • 15
  • 91
  • 109
  • 66
    This answer is out-dated. See http://stackoverflow.com/questions/1450285/how-to-define-custom-configuration-variables-in-rails/5053882#5053882 below – mattwynne May 27 '11 at 15:35
  • 9
    @matt: Is it outdated because Rails 3 has been released, or because *everyone* is now on Rails 3, or ...? – Lasse V. Karlsen May 27 '11 at 19:54
  • 1
    Thanks for pointing out the outdated. I hate that about Rails -- code from 1 year ago is too old. – jcollum Dec 15 '11 at 23:16
  • 2
    For anyone wanting to use the YAML method in Rails 3+, you'll have to replace `RAILS_ENV` with `Rails.env` and `RAILS_ROOT` with `Rails.root`. – rxgx May 17 '12 at 18:47
  • I tried rails_config. In the documentation they instruct me to register RailsConfig in my app.rb. I assume that app.rb = config/application.rb. But where in the application.rb should I put the register RailsConfig line? – Nhím Hổ Báo Apr 08 '15 at 19:58
70

In Rails 3.0.5, the following approach worked for me:

In config/environments/development.rb, write

config.custom_config_key = :config_value

The value custom_config_key can then be referenced from other files using

Rails.application.config.custom_config_key
Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
Rob Dawson
  • 1,349
  • 10
  • 21
  • 4
    Beware that if you set something only in production, and try to access it in another environment, it would complain `undefined method`. – lulalala Mar 15 '12 at 10:45
  • I Tried this in rails 4.1 and I'm getting errors, "...`method_missing': undefined method `store' for #...". I was trying to add "config.store.works" config variable. – Spundun Mar 19 '14 at 21:52
  • 1
    @Spundun You're getting that error, because Rails doesn't know what `store` is. In order to use the method in this answer, you can either rename your variable `store_works`, or create a `config.store` block with `works` defined therein. – Paul Pettengill Aug 21 '14 at 18:16
  • Thanks, I eventually figured that out. That these are nested hashes so I have to initialize empty hashes recursively if I'm to use dots in my config names. – Spundun Aug 21 '14 at 18:48
33

In Rails 4

Assuming you put your custom variables into a yaml file:

# config/acme.yml
development:
  :api_user: 'joe'
  :api_pass: 's4cret'
  :timeout: 20

Create an initializer to load them:

# config/initializers/acme.rb
acme_config = Rails.application.config_for :acme

Rails.application.configure do
  config.acme = ActiveSupport::OrderedOptions.new
  config.acme.api_user = acme_config[:api_user]
  config.acme.api_pass = acme_config[:api_pass]
  config.acme.timeout  = acme_config[:timeout]
end

Now anywhere in your app you can access these values like so:

Rails.configuration.acme.api_user

It is convenient that Rails.application.config_for :acme will load your acme.yml and use the correct environment.

pymkin
  • 4,304
  • 1
  • 21
  • 18
31

This works in rails 3.1:

in config/environment.rb (or in config/environments/.. to target a specific environment) :

YourApp::Application.config.yourKey = 'foo'

This will be accessible in controller or views like this:

YourApp::Application.config.yourKey

(YourApp should be replaced by your application name.)

Note: It's Ruby code, so if you have a lot of config keys, you can do this :

in config/environment.rb :

YourApp::Application.configure do
  config.something = foo
  config.....
  config....
  .
  config....
end
Alain Beauvois
  • 5,896
  • 3
  • 44
  • 26
23

Since Rails 4.2, without additional gems, you can load config/hi.yml simply by using Rails.application.config_for :hi.

For example:

  1. touch config/passwords.yml

        #config/passwords.yml
        development:
          username: 'a'
          password: 'b'
        production:
          username: 'aa'
          password: 'bb'
    
  1. touch config/initializers/constants.rb

    #config/initializers/constants.rb
    AUTHENTICATION = Rails.application.config_for :passwords
    
  1. and now you can use AUTHENTICATION constant everywhere in your application:

    #rails c production
    :001> AUTHENTICATION['username'] => 'aa'
    
  2. then add passwords.yml to .gitignore: echo /config/passwords.yml >> .gitignore, create an example file for your comfort cp /config/passwords.yml /config/passwords.example.yml and then just edit your example file in your production console with actual production values.

Evgenia Karunus
  • 10,715
  • 5
  • 56
  • 70
15

Rails 6 and 7

Many outdated answers, so adding one that is specific to Rails 6.

Application specific configuration goes in initializer files. Details are here: edge guides

Example:

config/initializers/foo.rb

module MyApp
  class Application < Rails::Application
    config.test_val = 'foo'
  end
end

Alternatively:

Rails.application.config.test_val = 'foo'

This can now be accessed as:

Rails.configuration.test_val

Many more possibilities. edge guides #custom-configuration

ex, you can also set up nested namespace configurations:

config.x.payment_processing.schedule = :daily
config.x.payment_processing.retries  = 3
config.super_debugger = true

or use config_for to load entire custom config files:

config/payment.yml

production:
  environment: production
  merchant_id: production_merchant_id
  public_key:  production_public_key
  private_key: production_private_key

development:
  environment: sandbox
  merchant_id: development_merchant_id
  public_key:  development_public_key
  private_key: development_private_key

Then load it with:

config/initializers/load_payment.rb

module MyApp
  class Application < Rails::Application
    config.payment = config_for(:payment)
  end
end
jpgeek
  • 4,991
  • 2
  • 28
  • 26
14

I just wanted to update this for the latest cool stuff in Rails 4.2, you can now do this inside any of your config/**/*.rb files:

config.x.whatever.you.want = 42

...and this will be available in your app as:

Rails.configuration.x.whatever.you.want

See more here: http://guides.rubyonrails.org/configuring.html#custom-configuration

smathy
  • 26,283
  • 5
  • 48
  • 68
8

Check out this neat gem doing exactly that: https://github.com/mislav/choices

This way your sensitive data won't be exposed in open source projects

Flov
  • 1,527
  • 16
  • 25
4

If you use Heroku or otherwise have need to keep your application settings as environment variables, the figaro gem is very helpful.

MikeH
  • 796
  • 7
  • 18
4

I created a simple plugin for YAML settings: Yettings

It works in a similar fashion to the code in khelll's answer, but you only need to add this YAML configuration file:

app/config/yetting.yml

The plugin dynamically creates a class that allows you to access the YML settings as class methods in your app like so:

Yetting.your_setting

Also, if you want to use multiple settings files with unique names, you can place them in a subdirectory inside app/config like this:

app/config/yettings/first.yml
app/config/yettings/second.yml

Then you can access the values like this:

FirstYetting.your_setting
SecondYetting.your_setting

It also provides you with default settings that can be overridden per environment. You can also use erb inside the yml file.

johnmcaliley
  • 11,015
  • 2
  • 42
  • 47
  • The official repo is now at: https://github.com/charlotte-ruby/yettings (SO reviewer rejected my edit saying it is too minor) – lulalala Mar 06 '13 at 10:05
4

I really like the settingslogic gem. Very easy to set up and use.

https://github.com/binarylogic/settingslogic

Rahil Sondhi
  • 656
  • 6
  • 7
  • 2
    Loving this so far. Putting your settings object at app/models/settings.rb gets you reloading in dev mode too. Win! – Mat Schaffer Nov 07 '11 at 16:41
2

I like to use rails-settings for global configuration values that need to be changeable via web interface.

cite
  • 778
  • 5
  • 12
  • 2
    I dint wanna use additional plugins etc, as I am learning rails, so the best way to do it would be without any plugins. – Shiv Sep 20 '09 at 16:09
  • Note this uses database to store configurations, which maybe too heavy for some people. – lulalala Mar 06 '13 at 09:26
2

Something we've starting doing at work is the ActiveSupport Ordered Hash

Which allows you to define your configuration cleanly inside the environment files e.g.

config.service = ActiveSupport::OrderedOptions.new
config.service.api_key = ENV['SERVICE_API_KEY']
config.service.shared_secret = ENV['SERVICE_SHARED_SECRET']
mdb29
  • 53
  • 7
-6

I would suggest good approach how to deal with configuration in your application at all. There are three basic rules:

  • change your configuration not a code;
  • use configurations over conditions;
  • write code that means something.

To have more detailed overview follow this link: Rails configuration in the proper way

paladiy
  • 9
  • 1