The Fast and the Furious On Rails

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
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,

packages a set of plug-ins commonly used to create sites, including an asset packager (to bundle and compress JavaScript and CSS files into a single download), Rspec (to support test-driven development), and RESTful authentication (to create and activate user accounts). You can download Bort with the command git clone git://github.com/fudgestudios/bort.git.

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.

Vroom, Vroom!

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 2.3.2
$ rails album -m paperclip.rb
    create  app/controllers
  applying  template: paperclip.rb
    plugin  paperclip

Unpacking objects: 100% (62/62), done.
From git://github.com/thoughtbot/paperclip
* branch            HEAD       -> FETCH_HEAD

   applied  paperclip.rb
$ 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.

# bort.rb
# from Jeremy McAnally, Pratik Naik
# based on bort by Jim Neath
inside('vendor') do
ÊÊrun "ln -s ~/commit-rails/rails rails"
plugin 'rspec',
ÊÊ:git => 'git://github.com/dchelimsky/rspec.git'
plugin 'rspec-rails',
ÊÊ:git => 'git://github.com/dchelimsky/rspec-rails.git'
plugin 'exception_notifier',
ÊÊ:git => 'git://github.com/rails/exception_notification.git'
plugin 'open_id_authentication',
ÊÊ:git => 'git://github.com/rails/open_id_authentication.git'
plugin 'asset_packager',
ÊÊ:git => 'http://synthesis.sbecker.net/pages/asset_packager'
plugin 'role_requirement',
ÊÊ:git => 'git://github.com/timcharper/role_requirement.git'
plugin 'restful-authentication',
ÊÊ:git => 'git://github.com/technoweenie/restful-authentication.git'
gem 'mislav-will_paginate', :version => '~> 2.2.3',
ÊÊ:lib => 'will_paginate',  :source => 'http://gems.github.com'
gem 'rubyist-aasm'
gem 'ruby-openid'
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.

  • inside() requires the path to a directory. This method changes directory to the named path and executes each command in the block within that directory. This inside() command is unique to Jeremy’s environment: he links vendor/rails (the application’s frozen Rails code) to Edge Rails found in ~/commit-rails/rails. (You can safely remove this block or adapt it to your own environment.)
  • The next series of instructions should be familiar: Each statement installs a plug-in. In addition to :git, you can also use :svn.
  • The next operator, gem, does not install a gem. Instead, per convention, it adds a gem.config entry to environment.rb to connote that the application depends on the named gem. Here, three gems are required: will_paginate to paginate results; rubyist-aasm (“acts as state machine”) to track sign-up progress from new user to registered user; and ruby-openid to support OpenID authentication.
  • The next statement, rake("gems:install", :sudo => true) is the same as the command sudo rake gems:install. It enumerates the gem prerequisities and installs the gems as root.
  • Finally, the boilerplate runs two generators, the equivalent of the commands…
    ruby script/generate authenticated user session
    ruby script/generate rspec

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 :init
git :add => "."
git :commit => "-a -m 'Initial commit'"

More Goodies

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.

Fatal error: Call to undefined function aa_author_bios() in /opt/apache/dms/b2b/linux-mag.com/site/www/htdocs/wp-content/themes/linuxmag/single.php on line 62