How to define custom configuration variables in Rails?
Asked Answered
O

15

363

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.

Ofori answered 20/9, 2009 at 4:17 Comment(2)
Duplicate: #593054Domicile
Slightly related: Don't forget to restart the server when adding new configuration variables.Idol
D
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
Diecious answered 20/9, 2009 at 5:11 Comment(5)
This answer is out-dated. See #1450785 belowExclamatory
@matt: Is it outdated because Rails 3 has been released, or because everyone is now on Rails 3, or ...?Faludi
Thanks for pointing out the outdated. I hate that about Rails -- code from 1 year ago is too old.Bind
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.Cementation
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?Tanana
M
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

Mischievous answered 19/2, 2011 at 22:14 Comment(19)
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: guides.rubyonrails.org/configuring.htmlThomsen
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.Uredium
This is assignment but how do you access this value then?Brooklime
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 (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?Savagery
I'm on Rails 3.0.4 and could access the config variable only by doing: Rails.application.config.custom_config_variable.Ellieellinger
Dude, simple: Path: config/environments/production.rb Config: config.whatever = false Access it anywhere: Rails.configuration.whateverAntiproton
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.Aram
Beware that if you set something only in production, and try to access it in another environment, it would complain undefined method.Perri
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.Flunky
Yeah as @Perri 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?Decerebrate
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.Vedi
@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.Tartarous
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?Mediate
@Tilo, lynks: Use this answer for > Rails 3.2: #4800528Baseburner
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 ?.Emlyn
This is not working in Rails 4.1 I get errors "...method_missing': undefined method store' for #<Rails::Application::Configuration:0x007f9f735b7240>..." if I try to add a variable like config.store.worksWafer
@Wafer I had the same problem, this will do the trick: https://mcmap.net/q/93698/-custom-rails-configuration-sectionPleurisy
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.Alpenstock
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.Dreamadreamer
D
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
Diecious answered 20/9, 2009 at 5:11 Comment(5)
This answer is out-dated. See #1450785 belowExclamatory
@matt: Is it outdated because Rails 3 has been released, or because everyone is now on Rails 3, or ...?Faludi
Thanks for pointing out the outdated. I hate that about Rails -- code from 1 year ago is too old.Bind
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.Cementation
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?Tanana
M
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
Mullins answered 21/3, 2011 at 10:29 Comment(4)
Beware that if you set something only in production, and try to access it in another environment, it would complain undefined method.Perri
I Tried this in rails 4.1 and I'm getting errors, "...method_missing': undefined method store' for #<Rails::Application::Configuration:0x007f9f735b7240>...". I was trying to add "config.store.works" config variable.Wafer
@Wafer 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.Dendroid
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.Wafer
T
34

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.

Tullis answered 3/10, 2015 at 7:51 Comment(0)
F
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
Florrie answered 9/1, 2012 at 20:3 Comment(1)
camelCase :o use snake_case!Allman
G
24

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.

Gleeson answered 28/7, 2015 at 23:28 Comment(0)
P
20

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
Prentice answered 26/5, 2021 at 8:20 Comment(0)
C
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

Cockfight answered 29/1, 2015 at 22:21 Comment(0)
S
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

Softa answered 30/9, 2011 at 13:12 Comment(0)
S
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.

Straitjacket answered 7/4, 2011 at 19:51 Comment(1)
The official repo is now at: github.com/charlotte-ruby/yettings (SO reviewer rejected my edit saying it is too minor)Perri
G
4

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

https://github.com/binarylogic/settingslogic

Gentes answered 7/6, 2011 at 21:5 Comment(1)
Loving this so far. Putting your settings object at app/models/settings.rb gets you reloading in dev mode too. Win!Lighten
S
4

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

Stridor answered 18/1, 2013 at 17:13 Comment(0)
F
2

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

Fisherman answered 20/9, 2009 at 12:25 Comment(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.Ofori
Note this uses database to store configurations, which maybe too heavy for some people.Perri
S
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']
Superadd answered 26/4, 2018 at 6:55 Comment(0)
Q
-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

Quotha answered 24/4, 2014 at 18:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.