Initialize those Settings

http://www.flickr.com/photos/whiteoakart/

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!

Rails Upgrade Makes a Query Frowny Face

In what I thought would be a quick and inconsequential upgrade to Rails 3.0.3 from 3.0.1 I ran into a problem. For some reason I am getting some rouge quotes around a join statement in one of my app’s queries.

Luckily I had a cucumber test to cover the scenario that uncovered this hot mess. So now I must step through the changes between 3.0.1 to 3.0.3 to see what caused this bummer of a query. Anyway this is what it looks like if you’re interested. I’ll post my findings when I come across them.

Using hassle gem for a happy Heroku/Sass marriage

I love Sass… there I said it. Go on tell my how much Sass sucks, I don’t care. I’ve been using it and have been in a happy code/developer relationship for quite some time now.

However there has been some hardship between Sass and I after trying to deploy my application to Heroku. The problem lies in that Heroku does not allow filesystem write access to anywhere but the temp directory. In a standard Rails application you would be putting your sass files in public/stylesheets/sass/, which would compile to public/stylesheets. This makes your app angry, APPLICATION SMASH.. ARGHHH.

So now that you have some background, have you run into this too? Yes… I thought so. Well it just so happens that I’ve got the cure for what ails you. Actually not me, more like this guy. It’s called Hassle and long story short, it is a gem/plugin that rewrites where your Sass files are compiled/served. You don’t have to do anything but install it.

Add this to your Gemfile and you’re pretty much done:

gem 'hassle'

Whoops! If you’re running a rails 3 app then you’re probably real mad at me right now. Well that’s what you get for not finishing my article. Don’t let it happen again! I forgive you.

Turns out that the straight up gem is not rails 3 ready as of yet, and totally hoses your app. Alas there is a lovely fork that provides the nurturing that I require.

gem 'hassle', :git => https://github.com/Papipo/hassle

So there you have it! Your Sass files are now written and served to/from /tmp which is a writable directory in Heroku. All of a sudden everyone is playing nice, hooray.

Just an FYI, some of the statements made in this article are fact and some are completely fabricated… believe what you will. The truth is out there.

This has actually been tripping me up a bunch lately on new rails3 projects.  I’m glad I stumbled across this because it does make everything easier.  As in I don’t have to root around for that rspec.rake file I had in another project.

I’m sure someone out there has had this problem too… hope this helps.