I often struggle with the correct way to set any kind of configuration on a class, especially when it is a class intended to integrate with an external API that usually needs several configuration values.

I initially implemented my own configuration pattern, before coming across this great pattern by ThoughtBot that has been used for their open-source library Clearance:

class MyApiIntegration 
  class << self
    attr_accessor :configuration

  def self.configure
    self.configuration ||= Configuration.new

  class Configuration 
    attr_accessor :api_key, :api_secret

This exposes a very simple API for configuring the object:

MyApiIntegration.configure do |config|
  config.api_key = "wow"
  config.api_secret = "api"

I found the attr_accessor on class << self particularly useful, as I had been running into issues with class_attribute, class-level variables, and cattr_accessor where I was losing configuration between test runs. The only issue I have with this code snippet is that the default configuration (if any) is not assigned until configure is called. I am going to experiment with this pattern in my investment time to try and identify a way of having the default configuration used if configure does not need to be called.

Thanks ThoughtBot!