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!