Here’s some example code I’ve used for storing configuration variables using Ruby on Rails. This code allows for defaults as well, so you only have to specify variables per environment if they override the default value.
This first file should be put in /lib/app_config.rb
.
# This singleton class stores configuration options.
# It makes use of Ruby's method_missing method
# Any option added to the application's config file
# is automatically available as a method of the same name.
#
class AppConfig
include Singleton
# This file is used to set the configuration options for the application.
CONFIG_FILE = "#{RAILS_ROOT}/config/application.yml"
def initialize
@parser = YamlAppConfigParser.new(CONFIG_FILE)
end
def method_missing(methId)
instance_sym = ("@" + methId.id2name).to_sym
instance_variable_set(instance_sym, @parser.send(methId)) unless instance_variable_get(instance_sym)
instance_variable_get(instance_sym)
end
end
The above code uses method_missing
to create methods on the fly that correspond to different configuration variables. Add the config variable, and it automatically becomes available as a method on the AppConfig singleton class.
You need this class to load and parse the yaml file that the data is stored in. It should be in /lib/yaml_app_config_parser.rb
.
# This class parses /config/application.yml
# It supports both default and environment options.
# Environment options override the default options.
class YamlAppConfigParser
def initialize(yaml_file)
@yaml = YAML.load_file(yaml_file)
end
def method_missing(methId)
if @yaml[RAILS_ENV] && @yaml[RAILS_ENV][methId.id2name]
@yaml[RAILS_ENV][methId.id2name]
else
@yaml['default'][methId.id2name]
end
end
end
The above 2 files you just put in your project and forget about. Then, you just add config values to the /config/application.yml
file, and they become available config variables that vary by environment.
Here’s what a basic/config/application.yml
might look like.
default:
facebook_app_id: adsf78yadfkjasdf807y
facebook_secret: adsf78yadfkjasdf807y
path_to_file_foo: /mnt/files/foo.bar
development:
path_to_file_foo: /User/MyUser/tmp/files/foo.bar
production:
facebook_app_id: my_prod_fb_app_id
facebook_secret: my_prod_secret
Notice that the production environment has its own facebook_app_id
and facebook_secret
values, while the development environment just uses the default values. That’s how this approach works – you override only what you need.
Now to access these values from your code is simple, you just call:
@facebook_app_id = AppConfig.instance.facebook_app_id
@facebook_secret = AppConfig.instance.facebook_secret
@path_to_file_foo = AppConfig.instance.path_to_file_foo
Then the variables you’ve set as above contain the configuration values specific to their environment.