How to define custom configuration variables in rails
Ruby on-RailsConfigurationRuby on-Rails Problem Overview
I was wondering how to add custom configuration variables to a rails application and how to access them in the controller, for e.g I want to be able to define an upload_directory in the configuration files say development.rb and be able to access it in one of my controllers.
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.
Ruby on-Rails Solutions
Solution 1 - Ruby on-Rails
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
Solution 2 - Ruby on-Rails
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
Solution 3 - Ruby on-Rails
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
Solution 4 - Ruby on-Rails
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.
Solution 5 - Ruby on-Rails
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
Solution 6 - Ruby on-Rails
Since Rails 4.2, without additional gems, you can load config/hi.yml simply by using Rails.application.config_for :hi
.
For example:
-
touch config/passwords.yml
#config/passwords.yml development: username: 'a' password: 'b' production: username: 'aa' password: 'bb'
-
touch config/initializers/constants.rb
#config/initializers/constants.rb AUTHENTICATION = Rails.application.config_for :passwords
-
and now you can use
AUTHENTICATION
constant everywhere in your application:#rails c production :001> AUTHENTICATION['username'] => 'aa'
-
then add passwords.yml to .gitignore:
echo /config/passwords.yml >> .gitignore
, create an example file for your comfortcp /config/passwords.yml /config/passwords.example.yml
and then just edit your example file in your production console with actual production values.
Solution 7 - Ruby on-Rails
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
Solution 8 - Ruby on-Rails
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
Solution 9 - Ruby on-Rails
Rails 6
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
Solution 10 - Ruby on-Rails
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.
Solution 11 - Ruby on-Rails
I really like the settingslogic gem. Very easy to set up and use.
Solution 12 - Ruby on-Rails
If you use Heroku or otherwise have need to keep your application settings as environment variables, the [figaro][1] gem is very helpful.
[1]: http://github.com/laserlemon/figaro "figaro"
Solution 13 - Ruby on-Rails
I like to use rails-settings for global configuration values that need to be changeable via web interface.
Solution 14 - Ruby on-Rails
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']
Solution 15 - Ruby on-Rails
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