Cucumber Scenarios – Redux

Back when I was a BDD n00b I had dwelled into different styles of writing Cucumber Scenarios here. After six to seven months of usage and reading The Cucumber Book by Matt Wayne, things are lot more clear than what it was then.

In this post I want to bust some misconceptions about Cucumber and shed some light into the way it needs to be used.

What is Cucumber?

First let us understand what Cucumber really stands for in the BDD eco-system. The book definition is like this –

Cucumber is a tool that facilitates discovery and use of a ubiquitous language within a team.

This understanding of Cucumber is critical before we jump into writing Cucumber Scenarios. It’s a tool for unearthing language of the domain and there by facilitating an understanding of the domain.

It’s primary focus is not an Integration Test Tool or worst an Unit Test Tool. In the end of it if it can help in catching Regression issues that is the happy side effect of using Cucumber.

Since the idea of Cucumber is to find the ubiquitous language of the domain, the Cucumber scenarios need to be worded carefully so that it makes lot of sense to the technical and functional teams. Cramming lot of technical details (like UI details) is not a great idea while coming up with scenarios. Cucumber scenarios goes on to become the living documentation of the system.

Declarative or Imperative?

Imperative Style

Scenario: Open Account
Given I am in new account page
When I fill in Name with "Arun"
And I fill in DoB with "25/1/89"
And I select "Male" from "Sex"
And I press "Submit"
Then I should see "Account created."

Declarative Style

Scenario: Open Account
Given I do not have an account
When I sign up for an account
Then my account has to be created

As evident from the two scenarios, imperative one is tied up to the UI implementation of the system. It doesn’t really reveal the intent of the scenario properly. The declarative one on the other hand is really working at
an abstract level and probably communicates well to both functional and technical people. The declarative style clearly reveals the intent more succintly to the reader.

Other problems inherent with imperative style is maintenance, a slight change in UI like change of button caption will lead to change in the Scenario definition itself, which seems not right because your domain hasn’t changed to ensue a change in the Ubiquitous language of the domain.

Outside-In Development

Early days of BDD I was under the misconception that outside-in development means we have to drive out our design from UI, then drill down to controller and models. That was just a stupid understanding from my
side. Later I realized it was just meant to say Outside of what we want to discover. So it is perfectly fine to use Cucumber first to build the Domain Model layer of the system and later build UI on top of it.

Courtesy : The Cucumber Book

As shown in the figure (courtesy: The Cucumber Book) above, it is perfectly valid and sensible to run your Cukes on top of the domain model and then switch to full blown integrated system. So in the first few days, probably you will be driving out the design on Domain Layer from Cucumber and once it is done you can step into building the UI on top of it.

The switch from Domain to UI would entail a change Cucumber support code to point to UI (through Capybara) to make the Scenarios pass.

The point to realize is that when you move from Domain Model to UI Layer the language of your scenarios are not changing it remains same.

Pitfalls & Myths

Cucumber is hard to maintain

Yes they can be extremely hard to maintain if you go by the imperative route. A small label change in UI will break scenarios. Lately I had met many Ruby developers in Agile Conf & Ruby Conf India, and the common rant against Cucumber was it was hard to maintain.

I am really not sure if you do Cucumber in Declarative Style will it lead to maintenance problems or not? Declarative style reveals us the understanding of the domain. Now if the domain itself changes, then your code has to change, your tests have to change and so your Cucumber Scenario has to change. I cannot quite clearly see how maintenance problem creep in if Cucumber is used the proper way it is meant to be.

Writing Imperative Style

If you intend to write Imperative style cucumber scenario then the best place to do that will be RSpec Integration Tests and not in Cucumber.

Picture this

When I fill in "Name" with "Arun"
When I press "Submit"

can also written in same readable way in RSpec as

fill_in :name, :with => "Arun"
click_button "Submit"

And other places where imperative style creeps in is

And I press "Submit"
Then I should be on account page
And I should see "Arun"
And I should see "25/01/1989"
And I should see "Male"

Here we are testing UI elements using elaborate Cucumber Scenarios. Probably the best place for this code to live is RSpec View Tests.

Such test add overhead to maintenance and do not promote any readability for the stakeholders. Worst it doesn’t help in arriving at the ubiquitous language of the domain.

Pushing Unit Tests to Cucumber

This the case of overusing Cucumber without relying on Unit Tests. Consider the Scenarios below

Scenario: Create Account
Scenario: Create Account without Name
Scenario: Create Account without DoB
Scenario: Create Account without Name & DoB

Probably difference in these Scenarios may be the flash message which gets displayed. There is no need for all such trivial variations sitting in Cucumber, instead the last 3 scenarios can be pushed to the RSpec Model or even Controller layer and Cucumber can be left with Create Account scenario in Declarative style alone.

Remember writing Cucumber is not an excuse for not writing RSpecs. Cucumber creators themselves heavily advocate to use Unit Tests when we drill down from failing cukes to domain layer.

Bloated Step Definitions

The Step Definition file needs to be maintained cleanly without cramming in lot of code into that. Each step definition should delegate to the Cucumber support layer through a neat DSL. One of the good things if you follow this strictly is that at the end of cycle you will be able to arrive at a clean DSL for your domain.

For example

Given /^When I sign up for an account$/ do
  sign_up :name => "arun", :dob => "25/01/1989"

As you can see in Step Definition it just call for a sign_up method, here we are not putting Capybara Steps or Model interaction code directly.

sign_up method can live independently in support layer inside a module like AccountDSL.

module AccountDSL
  def sign_up(params)
     visit new_account_path
     fill_in :name, :with => params[:name]
     fill_in :dob, :with => params[:dob]
     click_button "submit"

So the UI interactions are localized into the single method. And the Step Definition can be reused any where within multiple scenarios. Even if a UI redesign happen you need to bother only about changing AccountDSL::sign_up method.

Also before we got into the UI building, we might have worked with same scenario interacting directly with Domain Layer. At that point probably the sign_up method would have read like this

module AccountDSL
   def sign_up(params)

Once the UI is ready it is just the question of swapping the implementation of sign_up method.


As they say Sign of well-written specs: the –format documentation gives a nice summary of all the project features to any stakeholder (link).

Sign of well-written Cucumber Scenario is to promote understanding of the domain and to derive an unbiquitous language of the domain.


Tidying up your RSpecs – 1

This is a cross post from our company blog.

Almost everyone in Ruby world agrees that RSpecs are a great way to test code in both Ruby and Rails projects.

Today, I want to share some of the tips which I had learnt and used in my RSpecs which has really help to tidy up the RSpec code and output.

Explicit Subjects & Contexts

Consider a RSpec for a Rails Controller. Assume that controller actions require a user to authenticate himself before performing any of the actions. In order to test this aspect we can write RSpec like this

describe PlacesController do
  describe "access control" do
    describe "for non-signed in users" do
      it "should redirect to sign in page for delete :destroy" do
        delete :destroy, :id => "1234"
        response.should redirect_to(new_user_session_path)
      it "should redirect to sign in page for get :index" do
        get :index
        response.should redirect_to(new_user_session_path)
      it "should redirect to sign in page for get :show" do
        get :show, :id => "123"
        response.should redirect_to(new_user_session_path)

The above specs can be repeated for each and every action in the controller. Now when I run the above spec the output will look something like this.

for non-signed in users
  should redirect to sign in page for delete :destroy
  should redirect to sign in page for get :index
  should redirect to sign in page for get :show

The output doesn’t read really that great. One of the good guideline which I believe for writing good RSpec is that the output should be really readable like a prose and easily convey the behavior or intent of the code it tests. So it’s time to tweak the code and make the output more readable. Also if you look the code has lot of repeatition of response.should redirect_to all over the place. So let us clean up that with explicit subject and context.

describe PlacesController do
  describe "access control" do
    context "for non-signed in users" do

      subject { response }

      context "delete :destroy" do
        before { delete :destroy, :id => "1234" }
        it { should redirect_to(new_user_session_path) }

      context "get :index" do
        before { get :index }
        it { should redirect_to(new_user_session_path) }

      context "get :show" do
        before { get :show, :id => "123" }
        it { should redirect_to(new_user_session_path) }

Notice how I have used the subject {} to specify an explicit subject. The implicit subject for any RSpec is the class which is used with the describe at top. In the above case it would be PlacesController. By specifying an explicit subject we are declaring the object which need to evaluated for subsequent tests. In this case it has been set to the response object. The usage of context really makes the code much clean and readable. Basically it sets the context for each test case while running. Now if we run the RSpec the output looks much cleaner like this.

for non-signed in users
  delete :destroy
    should redirect to "/users/sign_in"
  get :index
    should redirect to "/users/sign_in"
  get :show
    should redirect to "/users/sign_in"

Here is another example of an explicit subject below. This is an RSpec for User Role assignments with CanCan.

describe Ability do
  context "Admin Role" do
    before(:each) do
      @admin = Factory(:admin)
      @ability =

    subject { @ability }
    it { should be_able_to(:manage,User) }
    it { should be_able_to(:manage, Restuarant)}
    it { should be_able_to(:manage,Place) }

The code really is looking succinct and clean with the usage of subject {} . Without the subject it would have been a drudgery to write the same piece with describe…it..end blocks.

Shared Examples

Now let us turn our attention to the technique of Shared Examples which keeps our RSpec code DRY. Here is an example which tests the Links appearing in a footer of the page based on the User Role.

shared_examples "footer" do |links|
  links.each do |link|
    it "with #{link}" do
      within("div#footer") do
        page.should have_xpath("//nav/ul/li/a[contains(text(),'#{link}')]")

describe "Footer" do
  extend LinkHelpers

   context "not signed in user" do
    before { visit search_home_path }
    it_behaves_like "a footer", normal_links

   context "Admin" do
     before(:each) do
      @admin = Factory(:admin)
     it_behaves_like "a footer", admin_links

The code is pretty self-explanatory. For a noumal user I want a bunch of links to appear in the footer. For an admin user I want another set of links to appear. In the code above normal_links method gives the array of links for normal user and admin_links gives the array of links for admin user. [Note normal_links and admin_links are methods defined in a module LinkHelpers which I am extending below describe]

Coming to the DRY part. The code for doing the actual testing is put under a shared_example “footer” and it is invoked with it_behaves_like call. Also note we can pass zero or any number of arguments to shared_example. In the example above it accepts a single argument of Array type.

Let us see the output of the above code:

   not signed in user
     behaves like a footer
       with About Us
       with Feedback
       with Disclaimer
     behaves like a footer
       with About Us
       with Feedback
       with Disclaimer
       with Manage Restaurant
       with Manage Place

Even though the behavior and output is correct, the above results and code doesn’t read proper. Probably we shouldn’t call display of footer as a behavior. RSpec to rescue again! We can customize what appears in the output (in this case “behaves like a”) as well as rename the function it_behaves_like to something which is more appropriate for the context.

So for diplay of a footer it may be good to have a function like it_has_a “footer” instead of it_behaves_like “a footer”. Now let us see how this done:

RSpec.configure do |c|
   c.alias_it_should_behave_like_to :it_has_a, 'has a'

shared_examples "footer" do |links|
   links.each do |link|
     it "with #{link}" do
       within("div#footer") do
         page.should have_xpath("//nav/ul/li/a[contains(text(),'#{link}')]")

describe "Footer" do
   extend LinkHelpers

   context "not signed in user" do
     before { visit search_home_path }
     it_has_a "footer", normal_links

   context "Admin" do
     before(:each) do
       @admin = Factory(:admin)
     it_has_a "footer", admin_links

In the above code RSpec.configure block actually aliases the it_behaves_like function it_has_a and specifies that “has a” should be the output instead of “behavies like a” while the specs are run. Let us check the output now:

   not signed in user
     has a footer
       with About Us
       with Feedback
       with Disclaimer
     has a footer
       with About Us
       with Feedback
       with Disclaimer
       with Manage Restaurant
       with Manage Place

To Conclude

  • Use context with describe and make the test more readable instead of just getting stuck with describe..describe…it kind of format.
  • Give a before {} block for any context to set any pre-conditions before running the context.
  • Wherever possible declare an explicit subject and reduce the cruft in the specs.
  • DRY up your RSpec with shared_examples.
  • Customize the method name and output by aliasing in RSpec.configure.

Hope this post was helpful, do share your thoughts if any!

Rails HABTM in Mongoid & Factory Girl

In Rails say you have a HABTM (N:N) relationship between two models

class User
has_and_belongs_to_many :posts

class Post
has_and_belongs_to_many :users

So what essentially it means is a Post can have many Authors and an Author can have multiple posts.
Now you want to test drive the thing by seeding test data in Factory Girl.

Here is an article for seeding data for 1:N relationships in Factory girl. But it doesn’t talk about HABTM relations.

I was playing around with factory girl and figured out a way to seed a post with authors.
Here is how you do it –

Factory.define :user, :class=>User do |user|
user.first_name "Alex"
user.last_name "Malcolm"
user.nick_name "Alexy" ""
user.password "foobar"
user.password_confirmation "foobar"
user.role "author"

Factory.define :post do |post|
post.title "Foo Post"
post.content "Bar content"

Factory.define :post_with_author, :parent => :post do |post|
post.after_create { |p| Factory(:user, :posts => [p]) }

Now in your Test class do
@post = Factory(:post_with_author)

Factory girl would have inserted the User for you and then a Post and updated the relationship.

Btw I the code above was tested in Mongoid/MongoDB and not on Active Record. But since its working in Mongoid there is no reason I see why it won’t work with Active Record natively.

Another thing which I found with Mongoid/MongoDB and HABTM is that unlike Active Record you don’t need a Join Table like Users_Posts – the reason being MongoDB doesn’t support join queries. So you have to lump the join table into the respective models.

The Mongoid stores HABTM relation in back-end something like this

> db.users.find()
{ "_id" : ObjectId("4dc2010ea38c3d0b50000003"), "first_name" : "Alex", "last_name" : "Malcolm", "nick_name" : "Alexy", "post_ids" : [
], "role" : "author" }

That is in the Users model you have an array of post_ids and similarly in the Posts Model you will have an array of user_ids.

And finally if its on Active Record it may be preferable to have has_many :through instead of has_and_belongs_to_many relation as this post says.

Cucumber Scenarios : The Dilemma

Off late I am exploring BDD with Cucumber & RSpec in Rails.

The first step in BDD after understanding the customer requirements is to come up with the User Stories in a particular structure. Read this brilliant article from Dan North if you want to know more on the structure of User Story in BDD.

Let’s say I am creating a simple blog app, a sample Scenario for Creating a Post can be written in two ways as shown below. These scenarios are as coded for Cucumber.

A pithy way

Scenario: Create Post
Give I am a registered User
And I have signed in
When I go to Create Post Page
And Create a Post and Publish it
Then I should see the Post in the Index Page

or a Detailed way

Scenario: Create a Post
Given I am a registered User with name "Arun", email "" and password "foobar"
And I sign in as ""
When I visit Create Post Page
And I fill up Title as "Foo Post"
And I fill up Content as "Bar Contents for Foo Post"
And I publish the Post
Then I should see message "Post was successfully created."
And I should see post in the index page

The RSpec Book touches on this topic. It calls the first approach Declarative Style and second one Imperative Style. The Book also advises to use the former way if the project is more like a single man show where developer dons analyst/tester/coder hats and go for 2nd approach if the project has a bigger team and a business analyst for writing scenarios.

But its really a touch and go topic and its really difficult to gauge to how much in depth we have to go. The declarative seems to be pretty concise with loaded step definitions, but the imperative style gives a fair idea of what it takes to accomplish something in the system. So if we have a little bit informed tech savvy customer, probably second approach may add lot of value and clear lot of confusion. The imperative style is kind of walking the customer through the UI flows of the system.

But the conundrum with imperative style is if we already have good RSpecs for the Views/Controllers our RSpecs may read a lot like the imperative scenario and may look redundant.

So I can do rspec spec --format doc to get detailed documentation of the flows like the Cucumber imperative style. But of course it may not be good idea to share RSpecs with a Business User.

As the RSpec book says perhaps we need to mix judiciously both and perhaps experience only will teach to balance that.

The trigger for me to write this post was I was trying to create Scenarios for a sample project I am doing and just one hour I spend switching a scenario between declarative and imperative and was pretty confused where I would/should settle.

Phusion Passenger + Apache2 for RoR

Ok here goes my little notes on making a small nifty Rails App run on Apache2 with mod_rails provided by Phusion Passenger.

The installation of mod_rails is pretty straight forward. The installation steps are small and well documented here plus you have the amazing rails cast by Ryan Bates.

After watching the videos and reading the steps well I thought its gonna be a breeze I am going to wind up in 15mts and going to enjoy the night! Sigh! But things went wrong a 15mts exercise consumed close 4/5hrs of my time.

Ok here is where the fun is all about – I use RVM to maintain my installs. The first step in passenger installation is obviously to install the passenger gem. Now I felt it would be good to put the passenger in global gemset rather than any specific one and there by making it available to all. So I did

rvm use 1.9.2@global

gem install passenger


In my system after the above step it said some libraries were missing in the system (Ubunut Lucid Lynx), so I had to correct those by manually installing them with apt-get. After I got all the dependencies installed I again ran the passenger install and everything went fine.

At the end of the passenger-install step, it would spew a few lines of code which we need to put it on apache2.conf file. For me those lines looked like

LoadModule passenger_module /home/arun/.rvm/gems/ruby-1.9.2-p136@global/gems/passenger-3.0.5/ext/apache2/
PassengerRoot /home/arun/.rvm/gems/ruby-1.9.2-p136@global/gems/passenger-3.0.5
PassengerRuby /home/arun/.rvm/wrappers/ruby-1.9.2-p136@global/ruby

Now I added a Virtual Host to Apache to point to my sample Rails App by adding the following to the apache2.conf

<VirtualHost *:80>
DocumentRoot /media/harddisk/work/ror/depot/public
<Directory /media/harddisk/work/ror/depot/public>
Allow from all
Options -MultiViews

So that is it – restart the apache and hit in your browser you should see your rails app. But hey! wait won’t entering make the browser go and search the Internet rather than your local system. Well yes, so we have to make a small exception in the file /etc/hosts. In the file add a line

Ok all set! now again enter the URL to your browser biff! now got a new error

no such file to load -- bundler

The error was obvious it was not able to find the bundler. But from terminal I gave

gem list -d bundler

It was showing proper output, means bundler gem was there up and kicking. Mind you this command I was giving from the gemset which I was working on. Then I started googling this error and got many suggestions and tried one by one and spent nearly 3hrs and couldn’t make any break through. It was really frustrating.

Then finally help arrived from Hongli Lai of Phusion Team through the Phusion Passenger Google Group. She was pointing to me that ruby I am using for Phusion given in apache2.conf file was pointing to global gemset while bundler was installed in the other gemset. So I had replace the line in apache2.conf to pick up the ruby from the gemset which I was working on. So suppose foo is your gemset change PassengerRuby line in apache2.conf to

PassengerRuby /home/arun/.rvm/wrappers/ruby-1.9.2-p136@foo/ruby

Yes! This worked. Now if you are running a static site things would start working now. But my sample app had some tables so when I fired up app in browser it was complaining that tables were missing in the production.

So if you run into a similar situation just migrate the tables to production with rake.
rake db:migrate RAILS_ENV="production"

In my case I had some load scripts as well which was for loading some sample data to tables, for loading those data into production use the rails runner with following option

rails runner -e production script/load_xxxxx.rb

That is it, now I see my rails app working well in my Apache2 server with mod rails.

Ok! here is a small tip, in order to restart the Rails App after changes you need not restart the server, you can give this command from Rails Application Root

touch tmp/restart.txt

Passenger would see the timestamp of restart.txt and reload the Rails App if needed.

Back to emacs for Ruby on Rails

I remember last Java Sun Tech Days @ Hyderabad, when James Gosling was asking the audience who all were out there still using old editors like emacs/vim. Hardly a bunch would have raised their hands. The point he was driving was that in this age, we should probably move away from these editors and get into the groove of modern IDEs like Eclipse/NetBeans as they give powerful features like refactoring, automated testing etc. So its not worth the effort to learn all those weird key combos to drive the work. Of course he was talking more in perspective of J2EE development.

So what makes me drive back in time to the good old editor of yester years? Well, first is I am now full time into Ruby on Rails. I started Ruby learning expedition with NetBeans. But then somewhere in between I learnt Oracle has stopped support for JRuby in NetBeans. So then I moved to gedit and installed all the relevant plugins to make it a gmate (the mac-textmate equivalent in Ubuntu). Even though it was too good than the conventional gedit, still a lot was desired. So finally I decided to take the plunge and get into emacs. The good old emacs which I had been using some 4-5 years back and then ditched it to enter the snazzy world of IDEs. First few days were time for refreshing those old commands C-x s and C-x c etc. After that things just rolled out fast.

Now I am fully hooked onto emacs – the beautiful editor of Unix. To facilitate Ruby/Rails development I went ahead and installed Rinari – The Ruby on Rails Minor Mode for emacs. From there there was no looking back. The awesome keys which Rinari provides has made Rails development a breeze. If you are a Rails guy you would savour this short cuts – a ready reckoner of keyboard commands in emacs for Ruby on Rails Projects.

C-c ; f c rinari-find-controller
C-c ; f e rinari-find-environment
C-c ; f f rinari-find-file-in-project
C-c ; f h rinari-find-helper
C-c ; f i rinari-find-migration
C-c ; f j rinari-find-javascript
C-c ; f l rinari-find-plugin
C-c ; f m rinari-find-model
C-c ; f n rinari-find-configuration
C-c ; f o rinari-find-log
C-c ; f p rinari-find-public
C-c ; f s rinari-find-script
C-c ; f t rinari-find-test
C-c ; f v rinari-find-view
C-c ; f w rinari-find-worker
C-c ; f x rinari-find-fixture
C-c ; f y rinari-find-stylesheet

Rinari makes navigating within the Rails Project a breeze. Say if you are in view page you do C-c ; f c it takes you to the controller of the corresponding page and from there do C-c ; f m you land in the model of that page. It’s intelligent to figure you out the correct file for that.

Also it includes the shortcut C-c; w which starts the webserver for you within emacs. The webserver logs are like just another buffer in emacs. So when some error crops up do a C-x b to switch to the logs then in the error line in the log just hit a you land at the source code line where error has occured.

On top of Rinari, its good also to install Ruby-Electric which helps in automatic bracket closure, indentation etc. Then add up AutoCompletion and RSense to get auto completion feature in emacs for Ruby/Rails code like any other modern IDE. This blogpost is a good reference to configure emacs for Ruby on Rails.

The good thing about emacs is its just not a editor its an ecosystem unto itself, each day I am discovering something new in emacs. Once you are proficient in emacs I think you need not go out to shell or anyother place everything can be accomplished within emacs. For instance I have started maintaining my calendar & dairy and daily notes within the emacs with M-x calendar command. I have started using emacs calculator for my math occassionally, now I am trying to bring in my google mail box within emacs, small pdf documents I read within emacs now.

So the clock has turned back – its sheer joy using emacs and learning those beautiful commands.

I am not sure if there is any other editor out there which has some much features rolled into it and allow customizations to crazy levels if you know a bit of lisp.

Installing RoR in Ubuntu

The real strength of Ubuntu/Debian system is its package manager which makes the upgrade and installs in the system a breeze. In this post I am going to talk about ways to install Ruby and Rails in Ubuntu system.

Perhaps the easiest way to install Ruby is to use the apt package manager. Well you can do
sudo apt-get install ruby

But it turns out that its a bad idea to use apt for installing Ruby in Ubuntu. Primary reason being that Ruby development goes real fast and Ubuntu package managers are bit slow in catching up with it. As of today Ruby 1.9.1 is available through apt-get, but Ruby currently is 1.9.2. Ok, that is one of the reasons for not using apt, the other major reason is that we need to have a mechanism to install and switch between multiple versions of Ruby and Rails and perhaps switch back and forth between them.

Say you have to work with Ruby 1.8.7 with Rails2.3 in one project and Ruby 1.9.2 with Rails3 in another one. Using apt to install various versions of the language makes this difficult. Enter RVM (Ruby Version Manager)

Ok, if you want to further convince yourself about reasons of not going with debian package manager read this.

Some Terminologies
A newbee in Ruby Land can be overwhelmed with the terminologies in this world, so let me first clear them before diving into the how-to’s of upping the RoR in Ubuntu machine

Gem – aka RubyGem is a package manager for Ruby. As apt is the package manager for Ubuntu you can think Gem is package manager for just Ruby Ecosystem. In apt you have .deb file, here we have .gem file which is called the gem file, gem is nothing but a packaged Ruby program or library. Analogous to Java World .gem file can be equated to .jar file. But gem provides command like gem install which you can use to install gems remotely (like apt-get install). Similar commands are there for remove.

RVMRuby Version Manager is a manager which helps in installing multiple versions of ruby language and gems. You can easily mix and match the language version with various gems and use them independently. It provides a neat way of separating the versions without any clashes. RVM does this through gemsets. Essentially it provides a compartment or work-area where you can start your work with Ruby.

Gemset – Gemset is like an environment provided by RVM. In a Gemset first you choose which version of Ruby to use and then you can add as many gems within that gemset. You can create as many gemsets as you want. For each gemset you choose the ruby version and add gems into the gemset.


Ok, I hope now you are comfortable with jargons, its time to dive deep into the installation steps.

Pre-reqs To get started make sure you have git and curl in your system. Assume all those into programming will already have that ready.

Install RVM Look through the steps for RVM Install here. Its pretty straightforward. Once we have the RVM, we can install Ruby and start creating gemsets.

To install ruby you have give command
rvm install 1.9.2

Here 1.9.2 denotes the Ruby Version.

Suppose you want to have 1.8.7 Ruby also in same system do
rvm install 1.8.7

Now that you have multiple versions of Ruby in your system, you have to decide which version to use, you can give
rvm use 1.9.2

or say to make 1.9.2 default
rvm --default use 1.9.2

Creating Gemsets
Now that you have Ruby ready, you have option to create gemset or you can even ignore this and use the default (the global gemset). I feel its always better to start by creating a gemset, so that later on you can easily switch to different version if needed.

To create your own gemset give command
rvm gemset create foo

So foo is the name of your gemset. Next step would be to associate a Ruby Version to the gemset and start using it. For that start using gemset foo give
rvm use 1.9.2@foo

So you are saying that you want to use Ruby 1.9.2 with gemset foo. Note above command also switches you to the foo gemset. So from now on if you do anything it will be within the gemset foo. That is to say suppose you install any gem like rails it will be within the gemset foo.

To check the gems within gemset give
gem list --local

Ok! now to the crux, to install Rails just have to give
gem install rails

Yup! that is it, you are up and running with Ruby on Rails!

Potential Pitfalls
When you install Ruby using the rvm install command it pulls out the source code and compiles it and then installs it. So you have make sure that relevant libraries are there in the system, especially the zlib.

In one of the system, where I was trying out, didn’t have zlib so after doing all the steps when I tried to install gems with gem install command it was giving error

$ gem install rails
ERROR: Loading command: install (LoadError)
no such file to load -- zlib
ERROR: While executing gem ... (NameError)
uninitialized constant Gem::Commands::InstallCommand

This was quite vexing issue I tried to install zlib with apt-get still couldn’t resolve it. So if you face this problem you can do the following steps

$ rvm pkg install zlib
$ rvm remove 1.9.2
$ rvm install 1.9.2 --with-zlib-dir=$rvm_path/usr

Essentially what it does is installs zlib with rvm. Then we remove Ruby and then compile and install Ruby again.

The best approach to tackle this will be to do this step before start of the installation

$sudo apt-get install build-essential bison openssl libreadline5 libreadline5-dev curl git zlib1g zlib1g-dev libssl-dev libsqlite3-0 libsqlite3-dev sqlite3 libxml2-dev libxslt-dev autoconf

Moving Ahead

RVM installs and maintains all the gems and gemsets in your home directory under .rvm/ folder.
Here under ~/.rvm/gems folder you can find info about all your gemsets

gems>ls -l
total 24
drwxr-xr-x 2 arun arun 4096 2011-01-30 00:29 cache
drwxr-xr-x 7 arun arun 4096 2011-01-31 18:07 ruby-1.9.2-p136@foo
drwxr-xr-x 2 arun arun 4096 2011-02-01 05:32 ruby-1.9.2-p136@foo1
drwxr-xr-x 7 arun arun 4096 2011-01-30 00:29 ruby-1.9.2-p136@global
drwxr-xr-x 2 arun arun 4096 2011-01-31 17:39 ruby-1.9.2p136@rails3tutorial

So there you can see the gemsets created by me. global is the default gemset created by rvm.

Suppose you want to download a gem and install it. Copy the downloaded gem file to $GEM_HOME.
Then you can give
gem install

Suppose you want to have Ruby RSS gem. Download it and copy it to $GEM_HOME. Then give gem install. The steps are listed below

gems>cp /media/harddisk/downloads/rubyrss-1.1.gem $GEM_HOME
gems>cd $GEM_HOME
bin cache doc gems rubyrss-1.1.gem specifications
ruby-1.9.2-p136@foo>gem install rubyrss-1.1
Successfully installed rubyrss-1.1
1 gem installed
Installing ri documentation for rubyrss-1.1...
Installing RDoc documentation for rubyrss-1.1...
ruby-1.9.2-p136@foo>gem list --local
rspec-mocks (2.3.0)
rspec-rails (2.3.0)
rubygems-update (1.4.2)
rubyrss (1.1)

While installing gems it’s better to avoid rdoc and ri doc which gets installed with the gem. These documentation consume space and increases time to install. Anyway most of us will be googling or consulting online docs while development so if needed we can avoid docs totally while installing any gem. For that give

gem install rubyrss-1.1 -d --no-rdoc --no-ri

Hope a new-bee would find this post useful and easily get on with RoR in Ubuntu.

Great References