Protecting the sanity of Rails developers is job #1! Reduce new project setup time and speed the installation of essential gems and plug-ins with new application templates.
Instant gratification is one of the real joys of developing software. Like many other crafts, coding shapes raw materials into a novel work. Tap-tap-tap and a new machine is born.
Perhaps it’s no wonder that so many developers have adopted frameworks such as Ruby on Rails. Given tools such as routes, the ActiveRecord object-relational mapping (ORM), migrations, and a vast collection of open source contributions, it’s easy to realize features quickly.
But before you go all fast and furious, you must first leave the driveway. In the case of Rails, prep typically requires the installation of your essential gems and plug-ins, a modicum of configuration, the (re)creation of helpful initializers, and more. Certainly, setup occurs once, but repetition quickly becomes painful — like driving the Audi R8 super car through Midtown traffic.
Here’s a picture of the R8 to emphasize the point. Ouch.
The Audi R8 super car
To simplify the creation process, thus saving the sanity of many a Rails developer, a number of bootstrap kits are available. Bort, for example,
The RailsKits website also offers a number of specialized kits, some for free and some for a nominal fee. Of course, you can also download any number of open source Rails applications to base your work on. (Be mindful of the terms of the license.)
Bort is very capable and I’ve employed it to launch some of my own projects. Moreover, you can easily extend Bort with additional plug-ins and other custom code to create your own kernel.
However, Bort has two significant limitations: if your form of application differs, Bort is of little use; and Bort doesn’t affect the system software. If you regularly require specific gems or other tasks to prep the system for the application, Bort is of little use.
But hang on there, Mr. Diesel. Rails 2.3 offers another, much more flexible approach: the application template.
Created by Jeremy McAnally and new to Rails 2.3, an application template (here, let’s call it a boilerplate to avoid overloading the term template). The application boilerplate is a set of instructions to generate a new Rails application and mold the entire environment to suit. The boilerplate is a simple Ruby script, albeit with calls to a number of specialized, domain-specific methods.
For instance, the boilerplate “language” includes the method-cum-keyword plugin to install a plugin during the generation of a new application. Thus, if you wanted to install the handy Paperclip plug-in into a new application instance, create the script paperclip.rb with contents …
plugin( 'paperclip', :git => git://github.com/thoughtbot/paperclip.git )
… and run the command rails album -m paperclip.rb…
$ rails --version
$ rails album -m paperclip.rb
applying template: paperclip.rb
Unpacking objects: 100% (62/62), done.
* branch HEAD -> FETCH_HEAD
$ ls album/vendor/plugins/
A Better Bort
Let’s march through a more lengthy example to learn more about the available boilerplate methods. Specifically, let’s look at Jeremy McAnally’s boilerplate to replace Bort. (Jeremy offers a number of boilerplates via his GitHub account.) Here is bort.rb.
# from Jeremy McAnally, Pratik Naik
# based on bort by Jim Neath
ÃŠÃŠrun "ln -s ~/commit-rails/rails rails"
ÃŠÃŠ:git => 'git://github.com/dchelimsky/rspec.git'
ÃŠÃŠ:git => 'git://github.com/dchelimsky/rspec-rails.git'
ÃŠÃŠ:git => 'git://github.com/rails/exception_notification.git'
ÃŠÃŠ:git => 'git://github.com/rails/open_id_authentication.git'
ÃŠÃŠ:git => 'http://synthesis.sbecker.net/pages/asset_packager'
ÃŠÃŠ:git => 'git://github.com/timcharper/role_requirement.git'
ÃŠÃŠ:git => 'git://github.com/technoweenie/restful-authentication.git'
gem 'mislav-will_paginate', :version => '~> 2.2.3',
ÃŠÃŠ:lib => 'will_paginate', :source => 'http://gems.github.com'
rake("gems:install", :sudo => true)
generate("authenticated", "user session")
The keywords of the boilerplate domain-specific language are largely self-explanatory, making the intent of an application template easy to comprehend.
In addition to these operations, you can create new routes with route(), add new rake tasks with rakefile(), and install an initializer with initializer(). Similar to initializer(), convenience methods lib(), vendor(), and file() add a file to the lib and vendor directories, and any directory relative to RAILS_ROOT, respectively.
For example, you could use initializer() to create a list of date formats you commonly use.
initializer 'date_formats.rb', <<-CODE
:date => '%m/%d/%Y',
:date_time12 => '%m/%d/%Y %I:%M%p',
:date_time24 => '%m/%d/%Y %H:%M',
:day_date => '%a %m/%d/%Y',
:day_date_time12 => '%a %m/%d/%Y | %I:%M%p',
:day_date_time24 => '%a %m/%d/%Y | %H:%M'
Once so defined, you can convert a date to a pretty string with simple code such as @message.sent.to_s( :day_date_time12 ).
You can even drop your newly-generated application into Git with keyword git.
git :add => "."
git :commit => "-a -m 'Initial commit'"
Application templates are sure to save you time and headaches when creating a new application. Happily, the same automation can be applied to an existing application, too. The new rake task rails:template can apply a boilerplate script to an existing body of code.
For instance, to add the Paperclip plug-in to an existing work, just point to the script:
$ rake rails:template LOCATION=~/templates/paperclip.rb
You can share boilerplate scripts as well. If the Paperclip template is located at http://example.com/templates/paperclip.rb.txt, simply point to the URL:
$ rails album -m http://example.com/templates/paperclip.rb.txt
Until a Rails Guide for application templates is available, you can read about all the boilerplate capabilities at Pratik Naik’s blog. If you craft a helpful application template, consider sharing it with Jeremy.
If you combine the features of application template, rake rails:freeze:edge, and config.gem, you should have little hassle sharing a complete, stand-alone application with others.
Until next time, happy tinkering.