Initialize those Settings

When starting a Rails project you will generally start loading in your ‘goto’ gems. You know, the ones that you are familar with and provide quick value for you and your project.
One of these for me is settingslogic. This has always been one of my first setup steps. This gem is great. It allows you to set your application settings in a YAML file and then gain access to that data in normal ruby object method calling syntax.
ex: Settings.aws.secret
Cool… now we’re on the same page. It’s a pretty simple gem to set up to boot! Just add it to your Gemfile to get started.
In my example above I was using a Settings constant. Let’s get that created. In an initializer I would create a file settings.rb.
ex: config/initializers/settings.rb
class Settings < Settingslogic
source "#{Rails.root}/config/settings.yml"
namespace Rails.env
end
That was easy! We’re just telling Settingslogic where to look for our config file and how to figure out different namespaces. Namespacing is key here because it allows us to have different setting entries based on environment. Now you are able to enter test keys for your payment gateway instead of the live production keys.
ex: config/settings.yml
defaults: &defaults
use_online_storage?: false
aws:
access_key: longstringofchars
secret: supersecret
bucket: immabee-usin-settingslogic
development:
<<: *defaults
test:
<<: *defaults
production:
<<: *defaults
use_online_storage?: true
Now the fun part… lets use this bad dog. Say I want to upload some files using the fantastic Carrierwave gem. This is about how your settings would look like.
ex: config/initializers/carrierwave.rb
CarrierWave.configure do |config|
config.fog_credentials = {
provider: 'AWS',
aws_access_key_id: Settings.aws.access_key,
aws_secret_access_key: Settings.aws.secret
}
config.fog_directory = Settings.aws.bucket
end
Notice how I’m just gaining access to my settings via the Settings constant using what appears to be method chaining? Pretty cool, right? This is not really a new concept, I just think Settingslogic encapsulates this functionality well.
If you peek back up at our settings.yml, you should notice that the method chaining maps cleanly to the nesting of the YAML file… easy peasy.
That’s pretty much it. Now, funny thing, the reason I started writing this article was to show you some tips I found valuable. Thought I should set up the article with an overview of Settingslogic so we’re all on the same page.
If you had the above code implemented and tried to start your server or console you will most likely hit a brick wall. By chance you were following along… this may look familiar:
uninitialized constant Settings (NameError)
Gross, right? What the hell is it talking about? If you were to use the Settings constant anywhere else in your app this would probably not be a problem. This issue has to do with the order in which files are getting loaded in our app. We’re trying to use Settings before it has been evaluated.
I hit this wall a lot because a lot of times the reason I want to use this method is to cleanse my initializers of data points that shouldn’t be stored as part of my app like various api keys.
Rails loads initializers top down in alphabetical order. This should be no surprise that the ‘s’ in settings.rb is coming after the ‘c’ in carrierwave.rb. ‘That sucks!’, you say? The fix is pretty simple, you just need to think out of the box a little. Just rename your settings.rb file to _settings.rb. This now reorders its place in the alphabetical listing and allows the Settings constant to get loaded before your other initializers.
Hooray, settings goodness can now be had by all!
