ConfigureMe
A really simple gem for helping to manage dynamic application configuration.
Installation
gem "configure_me"
Usage
Using ConfigureMe is easy. First, derive a class from ConfigureMe::Base. Then define your settings just as you would attributes.
class AppConfig < ConfigureMe::Base
setting :timeout
setting :max_items
end
Settings can also be given default values:
class AppConfig < ConfigureMe::Base
setting :min_password_length, :default => 8
end
To access the settings, just reference the class’s instance method, followed by the name of the setting:
# AppConfig.instance.min_password_length
=> 8
Changes to the configuration are made the same way:
# AppConfig.instance.min_password_length = 6
=> 6
# AppConfig.instance.min_password_length
=> 6
Nesting
You can also nest configuration classes. To nest one config under another, just call nest_me from inside the nested class, passing it the class you would like to nest it under. When an instance of the parent class is created, an instance of the nested class will be instantiated at the same time.
class MainConfig < ConfigureMe::Base
setting :site_name, :default => "Ninja Robot Monkeys"
end
class ExtensionConfig < ConfigureMe::Base
nest_me(MainConfig)
setting :secret_weapon, :default => "throwing star"
end
# MainConfig.instance.extension.secret_weapon
=> "throwing star"
The default behaviour when nesting is to use the name of the nested class (excluding “Config”) to create the accessor method. To override this behavior, just pass the alternate name to nest_me
class ExtensionConfig < ConfigureMe::Base
nest_me MainConfig, 'altextension'
...
end
# AppConfig.instance.altextension.secret_weapon
=> "throwing star"
Persisting
An easily editable configuration doesn’t do any good without persisting it. To store our configuration settings in the database, we need to generate an ActiveRecord model to store our settings.
# rails g configure_me Setting
This will create a model/migration, and an initializer to let ConfigureMe know what model it should use for persisting. You can call the model whatever you want, so long as you pass the correct name in the initializer. All that’s left is to tell ConfigureMe to actually persist our configuration. And its a one-liner:
class AppConfig < ConfigureMe::Base
...
persist_me
end
Now, when updating any setting, the new value will be written to the database as well as stored in memory. Settings are converted to YAML before being written, so complex values can be stored. When accessing a setting, the database is always consulted first, and if no value is stored, the default is returned or, if no default was specified, nil.
Caching
To really crank up the performance, you can enable caching of values. If you’re paying attention, the method to enable this should be obvious.
class AppConfig < ConfigureMe::Base
cache_me
end
Now, when values are accessed, the cache will be referenced before falling back to other means. If combined with persist_me, this can make dealing with dynamic site configuration perform much better than a database only solution.
Putting it all together
Here’s a complete configuration example:
class MainConfig < ConfigureMe::Base
persist_me
cache_me
setting :site_name
setting :admin_email
setting :theme, :default => 'spacecadet'
end
class UserConfig < ConfigureMe::Base
nest_me(MainConfig)
persist_me
cache_me
setting :min_username, :default => 8
setting :min_password, :default => 8
end
With this setup, we’ll have access to a total of 5 configuration options:
AppConfig.instance.site_name
AppConfig.instance.admin_email
AppConfig.instance.theme
AppConfig.instance.user.min_username
AppConfig.instance.user.min_password
All of which will be stored in the database when modified, and read from the cache when possible.