Blue squares

Configure Your Gem the Rails Way with Railtie

Alon Salant ·

A couple weeks ago we announced the release of the Log Weasel gem that adds useful tracing IDs to your numerous application logs.

We had the configuration down to a couple simple steps but I wanted to make it even easier, possibly requiring no configuration for some environments like Rails.

It turns out this is a perfect scenario for using Railtie. I won’t go into a detailed discussion of using Railtie except to say that it is the framework that ties all the pieces of Rails 3 together and is the mechanism available to you to tie your own functionality into the core of Rails.

For my use case, I wanted to use Railtie to:

  • Configure Log Weasel via standard Rails mechanisms
  • Mount Rack middleware
  • Other initialization including mixing in to Resque and Hoptoad

The entire source for the Railtie follows.

require 'rails'

class LogWeasel::Railtie < Rails::Railtie
  config.log_weasel = ActiveSupport::OrderedOptions.new

  initializer "log_weasel.configure" do |app|
    LogWeasel.configure do |config|
      config.key = app.config.log_weasel[:key]
    end

    app.config.middleware.insert_before "::Rails::Rack::Logger", "LogWeasel::Middleware"
  end
end

It is included in the main gem file with:

require 'log_weasel/railtie' if defined? ::Rails::Railtie

So we only require the Railtie if Rails is available and specifically Rails::Railtie which is only available in Rails 3. Early in the boot process Rails will discover and load all classes that extend Rails::Railtie.

The config object available to the Railtie is the application configuration object. The line:

config.log_weasel = ActiveSupport::OrderedOptions.new

allows us to set log_weasel namespaced configuration in Rails environment files like:

YourApp::Application.configure do
  config.log_weasel.key = 'YOUR_APP'
end

You can put this configuration in your environment.rb file to be shared among all environments or in environment-specific files to change the configuration per-environment.

The initializer block registers to run after the Rails environment is configured. It calls a LogWeasel.configure which does some more initialization for the gem. If you weren’t using Rails but wanted to use Log Weasel, you’d call this method explicitly.

Lastly, the initializer adds our middleware to the middleware stack and Log Weasel is good to go.

Conclusion

Railtie gives you many hooks in to the Rails framework stack and application lifecycle. The example in this post shows you how you can use it tie the configuration and loading of your own gem into Rails so that your users experience it working the Rails way.