Pete Hamilton

Creating Gems for Rails Assets

Today I found a javascript library which I wanted to include in a rails project I’m working on.

The library was Backbone.Validation and fter looking for a wrapper-gem and coming up empty handed, I decided to create my own. What follows is a walkthrough of the steps I took in order to create the gem backbone-validation-rails to wrap this library up so I could add it to my assets pipeline.

1. Creating the Gem Framework

Bundler is capable of initializing a new gem framework for you very easily.

bundle gem backbone-validation-rails
  create  backbone-validation-rails/Gemfile
  create  backbone-validation-rails/Rakefile
  create  backbone-validation-rails/LICENSE.txt
  create  backbone-validation-rails/README.md
  create  backbone-validation-rails/.gitignore
  create  backbone-validation-rails/backbone-validation-rails.gemspec
  create  backbone-validation-rails/lib/backbone-validation-rails.rb
  create  backbone-validation-rails/lib/backbone-validation-rails/version.rb

It creates a bunch of files and folders (which I cover later) and a README with some TODOs/blank sections and contribution guidelines).

2. Managing Versions

Since the backbone.validation gem will simply be a wrapper for the actual backbone.validation javascript library, we will make the version of the gem track the version of the library.

This is done by modifying lib/backbone-validation-rails/version.rb

module Backbone
  module Validation
    module Rails
      VERSION = "0.6.2"
    end
  end
end

3. Adding the Engine

Bundler has helpfully created a new module for our gem, however we need to use a Rails engine. It’s an empty class but it means that the resources for the gem (namely our JS library file) will be included.

If you have used dashes in your gem name, it will assume a modular structure and create a new nested module for each section.

require "backbone-validation-rails/version"

module Backbone
  module Validation
    module Rails
      class Engine < ::Rails::Engine
      end
    end
  end
end

4. Including the Assets

Download the files (css/js library) you’re wrapping and if given the option, choose the full (non-minified) version.

The reason I say this is that I included the minified version of backbone.validation in my gem originally and have since regretted it. I would prefer to have readability in development (console/inspector etc) and rely on minification in production using something like Uglifier.

I put the files in vendor/ since they’re externally maintained. This isn’t necessary, I just feel it’s a nice logical structure.

I then nest the folders in the same way as my app. For example, I put backbone.validation.js in vendor/assets/javascripts

mkdir -p vendor/assets/javascript
curl https://raw.github.com/thedersen/backbone.validation/master/dist/backbone-validation.js -o vendor/assets/javascripts/backbone-validation.js

5. Filling in the Gemspec

The file backbone-validation-rails.gemspec has a number of TODOs left in it. Description, Summary etc.

Fill these in, describing your new wrapper gem. For an example, see the one for backbone-validation-rails here

It’s also worth replacing the default file includes line:

gem.files = `git ls-files`.split($/)

with

gem.files = Dir["{lib,vendor}/**/*"] + [LIST, OF, OTHER, FILES, TO, INCLUDE]

I had seen this before in other gemspecs and personally feel it’s is a bit nicer than relying on git to grab your includes, especially for something simple like this.

6. Releasing to RubyGems

You’re going to want to push your code to github (for hosting and community love) and ruby gems (for easy distribution). To release your code to rubygems just run:

rake release

Note: In order to push to rubygems you will require an account and the first time you release a gem you will be asked to provide your credentials. From then on an api key is stored in ~/.gem/credentials

You can then visit RubyGems and look at your new gem up there for the world to see!