eddorre

Observations in Traffic Patterns After an I5 Bridge Lift

July 31, 2010 — 0 Comments

Interstate 5 or I5 is an Interstate Highway that runs parallel to the Pacific Ocean and extends all the way from Mexico to Canada. In the Portland-Metro area it’s home to some of the worst traffic snarls and the subject of much debate from commuters, environmentalists and everyone in between.

I myself, am a commuter, meaning that I live in Vancouver, Washington but I work in Portland, Oregon. Unlike some of my commuter brethren, I don’t hold a grudge against people that are anti-commuting; I see their point as equally as I see my own. I firmly believe that a solution won’t present itself until both sides drop the tribal/faction mentality, stop stereotyping and start work collaboratively towards a vibrant and workable metropolitan area.

Until that time, I5 is what it is – a traffic quagmire. Having resigned myself to this realization, I started trying to understand why I5 traffic is this way. Like any good geek, I started this process by collecting data. In a forthcoming article, I’ll describe in detail how I’m collecting the data, but for now I’ll just give a summary. Every 15 minutes, between the hours of 5 AM and 9 PM, an automated script will fetch a speed map of the Portland-Metro area from WSDOT (Washington State Department of Transportation).

Although I’m still early in the process of collecting the data, I found something interesting on July 21st. Although I have no hard data to support this (I wasn’t there and I only have the empirical evidence of the speed maps), I’m fairly certain that an I5 bridge lift occurred in the late morning.

Before we get to the data, I should note, I’m not a traffic engineer, I don’t hold a degree in Civil Engineering, I don’t work for a government agency and the images below are copyrighted by WSDOT. I’m just a web developer with a thirst for knowledge and an intense curiosity for how and why traffic systems work and don’t work.

Let’s look at the data, shall we?

Our story begins at 12:30 PM, traffic on both sides of the Columbia River seems to be flowing normally as evidenced by this traffic shot:

Fifteen minutes later, I5 is at a complete standstill heading southbound from Washington as well as heading northbound from Oregon. Conversely, traffic directly after the I5 bridge – in both directions – is free flowing. This is usually indicative of a bridge lift that allows marine traffic to pass.

Our next shot, 15 minutes later, seems to indicate that the bridge has been lowered. We can deduce this because of movement on I5 south from Vancouver; it is “Wide Open” just before the bridge and “Heavy” just north of that. On I5 north, there is a different story, traffic is actually getting worse as is evidenced by the “Stop and Go” section extending further into north Portland.

At 1:15 PM, on I5 south in Vancouver, we see the “Wide Open” status just before the bridge change to “Moderate” with everything else being “Wide Open”. On I5 north in Portland, we see traffic migrate from “Stop and Go” to “Heavy”; which seems to be a natural progression. You can also see a small band of “Moderate” traffic begin just south of the “Heavy” traffic. This may or may not be unrelated to the bridge lift since it’s separated by a patch of “Wide Open”, free flowing cars.

One hour after we observed the bridge lift, I5 south in Vancouver is free flowing; there are no more slow downs. However, I5 north in Portland still seems to be having issues. Right before the bridge, it’s migrated from “Heavy” to “Stop and Go” and it’s still experiencing “Heavy” traffic just south of the bridge.

At 1:45 PM, heading north on I5 in Portland, the band of “Heavy” transitions back to “Stop and Go” just like it was at 1:00 PM. I5 south in Vancouver remains unchanged.

At 2:00 PM, I5 south from Vancouver is still free flowing, but I5 north continues to experience issues. Right before the bridge, a small band of “Heavy” traffic materializes but the band of “Stop and Go” traffic just after that remains unchanged.

At 2:15 PM, I5 north is beginning to see some small measure of relief as the band of “Stop and Go” traffic transitions, once again, back into “Heavy” traffic. However, all is not well. Just before the bridge, things seems to be getting jammed up again as traffic transitions, once again, from “Heavy” to “Stop and Go”.

At 2:30, all bets are off on I5 north in Portland. The slowdown at 2:15 PM right before the bridge sends a traffic shockwave down I5 south, transitioning the “Heavy” traffic back into “Stop and Go” traffic. If that wasn’t enough, even further south, we now see a new patch of “Heavy” traffic. This new patch is the start of Rush Time traffic (Rush Hour is a misnomer as periods of heavy traffic on I5 north can go on for five to six hours). Because this is now Rush Time traffic, we can stop our sampling and take a look at the results.

So it easier to visualize, I’ve created a time lapse image of the event from 12:30 PM to 2:30 PM.

Ending Observations

It is common knowledge that in the morning commuters will jam I5 south as they head into Portland and beyond. In the afternoon, the inverse is also true, commuters jam I5 north bound as they leave their jobs and head home. This is not a disputed fact. However, it’s interesting that the data shows that I5 north can become quite a mess even when the bulk of commuters are still at their jobs (assuming that the earliest commuters start at around 6:30 AM and leave at 2:30 PM). This is something that’s rarely, if ever, discussed within the commuting debate.

It’s also clear that based on the data, I5 south in Vancouver will recover more quickly from a bridge lift than I5 north in Portland will. Within approximately 60 minutes of a bridge lift I5 south has completely corrected itself. In Portland, I5 north, doesn’t correct itself until Rush Time is over (on July 21st this doesn’t occur until 8:15 PM).

What causes this? I don’t have any data to support my suppositions so I honestly don’t know. If I were to take a wild guess it would be that the arterials on I5 north are poorly designed and this causes and inordinate amount of merging. Merging usually results in some slow down and in turn this slow down translates into a traffic shockwave that can reverberate for miles. I5 north in Portland is not the only culprit, the entrance to SR-14 eastbound in Vancouver is too close and requires drives to slow down to make the turn. During peak times, this slowdown will extend all the way to the Hayden Island entrance on I5 in Portland (this is the last entrance to I5 north from Portland) and essentially turns I5 north from a 3 lane Interstate into a 2 lane Interstate.

For those that are curious as to what happens before and after the bridge lift, I’ve create a time lapse image from the hours of 5 AM to 9 PM.

Installing Rails 3 (beta 3)

April 18, 2010 — 6 Comments

This article contains outdated information. Please refer to the new article.

I’ve been collecting Rails 3 links ever since the first beta hit but I’ve been putting off installing it because I’ve been terribly busy and some of the early problems that I was reading on Twitter (namely with Bundler) turned me off.

Yesterday, I finally had enough time to start the installation and documentation process. For those following this guide, I should warn you in advance, Rails 3 is a fast moving target. Stuff is changing all the time, so by the time that you come across this guide it might be out of date or not The Rails Way of doing things.

I’ll try to keep it updated as best I can, but keep that warning in mind.

One more thing, the following should work with *nixes, but for those curious, I’m using OS X — Snow Leopard.

Note: Don’t prefix sudo when installing or uninstalling gems into an rvm’d environment.

Let’s get started by installing RVM first. There are many ways to install RVM, but I chose the gem method.

sudo gem install rvm

Once the gem has been installed run the install process.

rvm-install

This should install and configure it for your shell (it did for me), but if it doesn’t, refer to the RVM install documentation for setting up your shell correctly.

I found that the gem version was a version behind the head version, so I updated it using:

rvm update --head

Followed by:

rvm reload

From some of the links that I’ve been reading, it’s been suggested that you install Ruby 1.9.2 for use with Rails 3. Using RVM, this is easy to do:

rvm install 1.9.2-head

Installing and compiling Ruby 1.9.2 takes a while.

Switch over to the 1.9.2-head version and let’s setup a Rails 3 gemset:

rvm --create use 1.9.2-head@rails3

Instead of installing a bunch of gems manually, we can use a gemset to do it for us.

curl -L http://rvm.beginrescueend.com/gemsets/rails3b3.gems -o rails3b3.gems

Once that has been downloaded, let’s import the gemset file:

rvm gemset import rails3b3.gems

If everything has gone well we should be able to see beta 3 when running the rails —version command:


rails --version
Rails 3.0.0.beta3

Note: If you get a rails/cli error here it’s possible that you already have another beta version installed from somewhere. This popped up a couple of times for me. The first time it happened, I uninstalled all gems named rails and re-installed the rails3b3 gemset. This took care of it but it came back, it’s probably easier to just clean your gems instead:

gem clean

Note: This will only clean the gems in your rvm’d environment. It won’t affect any other Ruby/RubyGems install.

Since I use RSpec for my testing framework, I installed those gems:


gem install rspec --prerelease
gem install rspec-rails --prerelease

At this point, Rails should be installed and waiting for you to create a new project using:

rails [path/project_name]

If you don’t specify a -d option to the rails command then it’ll use SQLite as the database, but you can always using the database of your choice:

rails [path/project_name] -d mysql|postgres|sqlite3

Once you’ve created a project open it up in your editor of choice and familiarize yourself with the Gemfile file.

You should pay attention to the :require directive on gems. Sometimes the gem name and the library name aren’t the same. For example, here is the aws-s3 gem with its require line:

# gem 'aws-s3', :require => 'aws/s3'

If you want to install Rails Edge then comment out or delete the line from the Gemfile:

gem 'rails', '3.0.0.beta3'

And uncomment the line:

# gem 'rails', :git => 'git://github.com/rails/rails.git'

If you’re having weird issues with Rails 3, upgrading to Edge might be the way to go. I know that it fixes and error in a form bypassing validation in Rails3Beta2, so it might be worth it.

You should also note the database gem that’s listed in your Gemfile. In a simple project that I created it was listed as:

gem 'sqlite3-ruby', :require => 'sqlite3'

Since I installed RSpec and RSpec Rails, I should tell Bundler about them. Note that I’m only installing them in the test environment.

I added the following to the bottom of the Gemfile:


group :test do
  gem 'rspec', '>= 2.0.0.beta.7'
  gem 'rspec-rails', '>= 2.0.0.beta.7'
end

After you’ve edited your Gemfile to your liking, install them with Bundler:

bundle install

Once all of the gems have been installed, you should have a working Rails application that you can test by running:

rails server

If everything has gone according to plan you should have a working Rails3Beta3 app running.

Tutorial: Filtering Results with jQuery UI Slider and Rails 3 Beta 3

May 25, 2010 — 3 Comments

A few months ago, I wrote an tutorial article titled Tutorial: Filtering Results with jQuery UI Slider and Rails.

After getting Rails 3 Beta 3 up and running, I wanted to get an app running from scratch using Rails 3 Beta 3. I chose the app in the original tutorial because it was dead simple and wouldn’t take much time at all to do.

Before proceeding with this tutorial, make sure that Rails 3 Beta 3 is running. Use my tutorial. I’ll wait…

All installed and ready to go? Good. Without further ado, here we go.

Setting Up

First of all, let’s visualize what we want to achieve. In my example, I have 20 dummy stocks that I want to filter down based on a high and low price. Here is a sample screen shot:

stocks

We’re going to start from scratch from a brand new Rails project. So we’ll have to create it:

rails jquery_slider_rails3

Since we didn’t pass a -d option, the Rails 3 generator will use the SQLite database by default. That’s perfectly fine for this example.

Bundle me Some Gems

Now that Rails has created a new project for us, let’s open it up and take a look at the Gemfile.

If you’ve followed my tutorial to install Rails 3 Beta 3, this file should be familiar by now and you’ve probably already installed some gems with Bundler. If not, let’s do that now.

Make sure that you see the following line for SQLite:

gem 'sqlite3-ruby', :require => 'sqlite3'

Since we’re going to do some simple model specs, we’ll need to install RSpec and RSpec Rails. This is done by editing the Gemfile and adding the following:


# Bundle gems for certain environments:
group :test do
  gem 'rspec', '>= 2.0.0.beta.7'
  gem 'rspec-rails', '>= 2.0.0.beta.7'
end

You’ll notice that these gems belong to their own test group. This means that those gems will only be loaded in the test environment.

We’re also going to use the Faker gem to generate some fake names for our stocks. Add the following to the Gemfile (I put mine directly beneath the sqlite gem declaration).

gem 'faker'

Now that we have the necessary gems defined, we’ll go ahead and install them using Bundler.

bundle install

Generating our Model

Before we can start creating our model, we’ll need to tell Rails that we’re using RSpec. First let’s expose the generators to Rails.

Open the application.rb and uncomment the config.generators block so that it looks like this:


config.generators do |g|
  g.orm             :active_record
  g.template_engine :erb
  g.test_framework  :rspec, :fixture => true, :views => false
end

Then run the rspec installer.

rails g rspec:install

Once that’s been completed, we’re ready to move onto the next step, setting up our model.

rails g model Stock name:string price:integer

You should see something like:

      
      invoke  active_record
      create    db/migrate/20100418065519_create_stocks.rb
      create    app/models/stock.rb
      invoke    rspec
   identical      spec/models/stock_spec.rb
   identical      spec/fixtures/stocks.yml

Defining our Specs

Let’s start defining some behavior for our app. First we want to make sure that we can create a stock with a name and a price. Open the file stock_spec.rb in ~/spec/models and remove any generated code so that it looks like:


require 'spec_helper'
describe Stock do
end

Add the following lines in between the describe block:


  it "should be valid with valid attributes" do
    stock = Stock.new(:name => 'Foo', :price => 1)
    stock.should be_valid
  end

You’ll get an error if you run your spec right now because we haven’t created a test database or defined the migration. Go and run rake or rake spec if you want to see a spectacular failure in your terminal.

Since we actually want the spec to pass, let’s go and create our databases and define our migration. Creating databases is just like in previous versions of Rails.

rake db:create:all

Open the migration file located at ~/db/migrate. Most of it should already be defined but since we’re going to be filtering on price, we’ll go ahead and create an index on that column.

Your migration file should look like this:


class CreateStocks < ActiveRecord::Migration
  def self.up
    create_table :stocks do |t|
      t.string :name
      t.integer :price

      t.timestamps
    end
    
    add_index :stocks, :price
  end

  def self.down
    drop_table :stocks
  end
end

Migrating, just like creating database, is no different in Rails 3.


rake db:migrate
rake db:migrate RAILS_ENV=test

Now that we have a test database and migration run, we can run our spec using rake. You should see something like:


..

Finished in 0.0418 seconds
2 examples, 0 failures

Let’s define some more specs. We’ll always want to order the stocks by lowest price (unless we override it). Note: Normally this is where you’d start using a factory like Factory Girl or Machinist but the app is so simple it’s overkill.

Our second spec looks like this:


  it "should return stock in price ascending order by default" do
    stock_1 = Stock.create(:name => 'Foo', :price => 300)
    stock_2 = Stock.create(:name => 'Foo', :price => 400)
    stock_3 = Stock.create(:name => 'Foo', :price => 200)
    stock_4 = Stock.create(:name => 'Foo', :price => 100)
    
    Stock.all.should == [stock_4, stock_3, stock_1, stock_2]
  end

If we run our spec, it’ll fail because the default order defaults to name DESC. So we have to write some implementation code to fix our failing spec.

Open the stock.rb file located in ~/app/models. Since we want it always to order our stocks by price (lowest to highest), we can use something that was introduced in Rails 2.3; default_scope.

If you’re familiar with Rails 2, you’ll notice that the syntax of this is a bit different.


default_scope order('price ASC')

If we run rake spec again, we’ll see that we have another passing spec. Let’s move onto the next one.

We also know that we want to filter our stock prices based on low and high value dynamically. We can write a simple spec for this too. Basically what we want is "give me all of the stocks that have a price between 200 and 300 inclusive.


  it "should filter out stocks that aren't in our range" do
    stock_1 = Stock.create(:name => 'Foo', :price => 100)
    stock_2 = Stock.create(:name => 'Foo', :price => 200)
    stock_3 = Stock.create(:name => 'Foo', :price => 300)
    stock_4 = Stock.create(:name => 'Foo', :price => 400)
    Stock.filter(200,300).should == [stock_2, stock_3]
  end

Again, if we run rake spec, we’ll have a failing spec since we haven’t created the filter method. For this, we’ll be relying on scopes again.


scope :filter, lambda { |low, high| where(:price => low..high) }

If you’re familiar with Rails 2, you’ll notice that named_scope has been replaced with just scope. Also, you can see some of Arel’s new syntax.

Running rake spec gives us our next passing spec.

Creating our controller and views

Rails 3 syntax for creating controllers is pretty much unchanged from previous versions of Rails.


rails g controller stocks index

This creates our stocks controller with an index method. Open the newly created file at ~/app/controllers/stocks_controller.rb. For now, let’s just display all of the stocks and then we’ll worry about filtering them down.


  def index
    @stocks = Stock.all
  end

Open the corresponding view file by going to ~/app/views/stocks/index.html.erb.

Let’s create a simple view.


<h1>Stocks</h1>

<div id="x_slider"></div>

<div>
  <p>Showing all stocks between <span id="x_low_selected"><%= @price_range.first %></span> and <span id="x_high_selected"><%= @price_range.last %></span></p>
</div>

<ul id="x_stock_list">
  <%= render @stocks %>
</ul>

As you’ll notice, I’ve rendering out the variable @stocks in order for this to work, we have to create a stock partial. In ~/app/views/stocks we’ll create a new empty file with the file name of _stock.html.erb with the following code:


<li>
  <p><%= stock.name %></p>
  <p><%= stock.price %></p>
</li>

The render method has gotten pretty smart as of late, so we don’t have to write our own each do loop here as long as the name of the instance variable (@stocks – plural) matches the name of the partial (_stock.html.erb – singular).

Astute readers will notice that I’m referencing an instance variable called @price_range. If you try to load the app right now in the browser, you’ll get an error since we haven’t set up the @price_range variable. In the previous tutorial, I had a class method on stock that grabbed the lowest and highest prices and put them into an array. We’ll duplicate that now.

Back to RSpec

Before we define the class method, we should define a spec for it.


  it "should return the highest and lowest stock prices" do
    stock_1 = Stock.create(:name => 'Foo', :price => 100)
    stock_2 = Stock.create(:name => 'Foo', :price => 200)
    stock_3 = Stock.create(:name => 'Foo', :price => 300)
    stock_4 = Stock.create(:name => 'Foo', :price => 400)
    Stock.low_high_prices.should == [100, 400]
  end

Now we just need to create our class method. It’s a simple one:


  def self.low_high_prices
    [Stock.minimum(:price), Stock.maximum(:price)]
  end

Running rake spec now gives us another passing spec. We’re getting close to spinning up the app but we’ll want to create some dummy data first.

Loading Sample Data

We can (mis)use the rake db:seed for this purpose. Remember that faker gem that we put into our Gemfile a long time ago? Here is where we’ll use it.

Open up the seeds.rb file located at ~/db/seeds.rb and we’ll add the following:


20.times do
  Stock.create(:name => Faker::Lorem.words(1).join, :price => rand(5 * 100))
end

This just creates a stock with a random name (thanks to Faker) with a random price. One thing of note here. The words method in Faker::Lorem creates an array. We really want this to be a string but since we’re using Ruby 1.9.2 we can’t just call a .to_s on it as the just returns and array with a string in it. I found that using .join without any arguments produces the result that we want.

Let’s load up our sample data.


rake db:seed

Now we should have 20 dummy stocks waiting for us. Let’s take a look.

Booting the Application

Before we can actually see anything in the browser, we can to create a simple resourceful route for our stocks. Routing is one of the things that’s changed dramatically in Rails 3 so I suggest that you read through the commented code in the routes files (~/config/routes.rb).

Once you’ve given the routes file a once over, let’s go ahead and add our route. I Added mine right at the top:


resources :stocks

Simple, isn’t it?

In your terminal fire up a web server by running


rails server

Now we’re ready to see something in our browser. Load up http://0.0.0.0:3000/stocks and you should see the stock list.

Let’s Make it Dynamic

In order to make this dynamic, we’re going to have to download some files.

Since we’re opting to use jQuery, we’re going to use the Rails 3 jQuery specific driver. Find the rails.js in ~/public/javascripts and remove it. Download the jQuery driver to the ~/public/javascripts directory.

We’ll need to install jQuery and jQuery UI but we can kill two birds with one stone by downloading jQuery UI. The download will come in a zip file, extract the contents and copy the contents of the js directory to ~/public/javascripts.

You’ll also need to copy the CSS file located in [extracted_zip_file]/css/[theme_name] to ~/public/stylesheets. Finally copy the contents of the images directory to ~/public/images.

I’ve noticed that there is a little tweak that we have to make to the CSS file. Open it up and do a find and replace on ‘images/’ to ‘/images/’. This will prevent Rails from searching for the images in ~/stylesheets/images/…

Once all of the Javascript files have been downloaded, we need to tell Rails to use them. Open the application.html.erb file in ~/views/layouts and add the following lines inside the head tag:


  <%= stylesheet_link_tag :all, 'jquery-ui-1.8.custom' %>
  <%= javascript_include_tag 'jquery-1.4.2.min', 'jquery-ui-1.8.custom.min', 'rails' %>
  <%= csrf_meta_tag %>

The jQuery UI slider library takes care of most of the heavy lifting. Here is the final slider Javascript code with an explanation below it of all of the settings.


<script type="text/javascript">
  $(function() {
    $("#x_slider").slider( { 
      range: true,
      step: 10,
      max: <%= @price_range.last %>,
      min: <%= @price_range.first %>,
      values: [<%= @price_range.first %>, <%= @price_range.last %> ],
      stop: function(event, ui) {
        var prices = $('#x_slider').slider('option', 'values');
        $('#x_low_selected').html(prices[0]);
        $('#x_high_selected').html(prices[1]);
        $.ajax({
          type: "GET",
          data: ({ low: prices[0], high: prices[1] }),
          url: 'http://0.0.0.0:3000/stocks',
          dataType: 'script'
        });
      }
    });
  });
</script>

Before we bind the slider to our div, we’ll wrap everything in a convenience function to make sure that the DOM is loaded.

Next we bind the slider by simply writing:


$("x_slider").slider( { options here }

As you can see in the code above, the slider takes several options (see full documentation for all options):

  • Range
    • When this is set to true, you’ll get two or more points on the slider
    • Step
    • This is the value that the slider decrements or increments every time you move a point
  • Max
    • The maximum value of the slider
  • Min
    • The minimum value of the slider
  • Values
    • An array of low and high points on the slider
  • Stop
    • This is an event that is fired when a point on the slider stops moving

In the stop event there is a bunch of stuff going on. First, I set a price array to the set points on the slider so I can use them later for updating the user of the min and max values as well as passing those in as parameters to the ajax call.

This code snippet simply replaces the min and max values on the page:


$('#x_low_selected').html(prices[0]);
$('#x_high_selected').html(prices[1]);

The ajax function also has several options:

  • Type
    • This is the type of HTTP request. A simple GET request will do here
  • Data
    • These are the variables that we’ll be sending along
  • URL
    • This is the URL that we’ll be hitting – this assumes that you’ve started the web server using script/server or mongrel_rails
  • DataType
    • I originally set this to html thinking that is what I wanted, but that’s the wrong call. You’ll want to use script if you want to return fragments of HTML otherwise you’ll return the whole page in HTML form (layout and all).

Wiring up the Slider to the Controller

We have one more thing to do in order to get our application up and running. We need to tell the controller to do its job.

Open the stocks_controller.rb file in ~/app/controllers/stocks_controller.rb and create an index method if one doesn’t already exist and populate it with the following:


  def index
    unless params[:low] && params[:high]
      @stocks = Stock.all
    else
      @stocks = Stock.filter(params[:low], params[:high])
    end
    
    @price_range = Stock.low_high_prices
  end

Since the the slider uses ajax for communication with the server, we’ll create an index.js.erb file in ~/app/views/stocks.

The file contains some simple Javascript code to execute:


$("#x_stock_list").html("<%= escape_javascript(render(@stocks)) %>");

With that little bit of Javascript code, every thing should be set to start up the application. To test it, start up the web server with the rails server command. Now in your web browser, go to http://0.0.0.0:3000/stocks and see the results.

Like before, I’ve made the code available for this tutorial on Github.

Using Ruby Enterprise Edition and Passenger on OS X with RVM

July 21, 2010 — 6 Comments

Ever since I installed Ruby 1.9.2-head with RVM (Ruby Version Manager) I’ve become a convert of using it to manage all of my Ruby installs.

Last week I decided to install Ruby Enterprise Edition on my development environment as my default Ruby install. My motivation for this was two-fold; better memory management and a comment by Laurent Sansonetti (one of the authors of MacRuby and works at Apple) on an article written by Robby Russell titled Installing Ruby on Rails, Passenger, PostgreSQL, MySQL, Oh My Zsh on Show Leopard, Fourth Edition.

The comment left by Laurent suggested not to rename the default Ruby install (and then symlinkling the Ruby installed via Ports) but to manage it by setting the load path.

Using RVM, we can install any Ruby version we want and have it set as the default Ruby instance easily. Let’s see how it’s done.

Note: The following documentation worked on my install of OS X. When encountering an error with the following instructions refer to the RVM documentation.

Installing the RVM Gem

There are multiple ways to install RVM, but I chose the gem install method (even if it is listed as not recommended in the documentation).


sudo gem install rvm

Installing RVM and Adding Hooks to Your Shell (bash, zsh, etc.)

Once the gem has been installed, you can now run the rvm-install command to add the hooks to your shell by running the following:


rvm-install

After RVM has been installed, you’ll be prompted to change something in your shell profile (the end of the install process will provide you with a code snippet). Since I’m using Oh My Zsh, and therefore the z shell (zsh), I opened up my .zshrc file located at /Users/carlos/.zshrc and pasted the code snippet at the bottom of the file.

Here is an example (the code snippet might be different depending on your shell and the version of RVM that was installed):


if [[ -s /Users/carlos/.rvm/scripts/rvm ]] ; then source /Users/carlos/.rvm/scripts/rvm ; fi

Updating RVM to the Latest Version

The gem version of RVM seems to be a little behind (this may be why it’s not recommended) so we’re going to update it. This updates RVM to the latest, greatest version.


rvm update --head

Installing Ruby Enterprise Edition and Dependencies

As the title of this post suggests, we’re going to be installing Ruby Enterprise Edition. According the web site, using Ruby Enterprise Edition has the potential to reduce Ruby memory consumption by 33% (on average) when used in combination with Phusion Passenger.

Before we can start installing Ruby Enterprise Edition we need to install Readline.


rvm package install readline

Once that’s done, we’re ready to get to the main event; installing Ruby Enterprise Edition.


rvm install ree -C --with-readline-dir=$HOME/.rvm/[yourusername]

Usually it will take some time for Ruby to be downloaded, compiled and properly installed with RubyGems support. When that’s done, you can switch over to your new RVM Ruby interpreter:


rvm use ree

Installing RubyCocoa for Use with the Passenger Preference Pane

Passenger is easiest to administer with the Passenger Preference Pane but it has some dependencies that we’ll have to install in order for it to work. If you don’t wish to manage virtual hosts with the Passenger Preference Pane, you can skip down to the next section.

Installing RubyCocoa

At the time of this writing, RubyCocoa 1.0.1 has been released but it’s broken at this time so we’ll have to rely on RubyCocoa 1.0.0.

Let’s download this from source and build it:


tar xzf RubyCocoa-1.0.0.tar.gz && rm RubyCocoa-1.0.0.tar.gz && cd RubyCocoa-1.0.0

ruby install.rb config --build-universal=yes
ruby install.rb setup
sudo ruby install.rb install

To make sure that RubyCocoa you’ll need to pop open an IRB session:


irb
require 'osx/cocoa'

If everything has gone well, you’ll see the shell return ‘true’ and you’re ready to install the Passenger Preference Pane

Installing and Configuring Passenger

Note: If you already had a development environment up and running, you’ll need to re-install your gems into the new RVM’d environment. When installing a gem into an RVM’d environment, do not prepend the command with sudo.

Before we can install Passenger, we’ll need to generate some wrapper scripts. This is done with the following:


rvm ree --passenger

Since the Ruby Enterprise Edition suggests using it with Passenger, we’ll go ahead and install the gem now.


gem install passenger

Once the gem has been installed, we need to to make sure that Apache is running; open up the System Preferences and then the Sharing applet. Make sure that Web Sharing is checked. Doing so will start the Apache web server.

Since Apache has been installed we need to have Passenger and Apache be friends. Start off by adding the Passenger module to Apache:


rvmsudo passenger-install-apache2-module

Towards the end of the installation process, you’ll be prompted to copy some information to put into your Passenger configuration file. There is a catch though, the Passenger install has no idea that you’re using RVM so the last two lines have inaccurate information (they are most likely referencing your system Ruby instance). The fix for this is easy though, you’ll just have to change the references to point to your RVM’d instance instead.

Here is an example from my install (obviously you’ll want to replace [yourusername] with your actual username:


LoadModule passenger_module /Users/[yourusername]/.rvm/gems/ree-1.8.7-2010.01/gems/passenger-2.2.11/ext/apache2/mod_passenger.so
PassengerRoot /Users/[yourusername]/.rvm/gems/ree-1.8.7-2010.01/gems/passenger-2.2.11
PassengerRuby /Users/[yourusername]/.rvm/bin/passenger_ruby

As mentioned, the above code snippet needs to be added to a passenger configuration file which I normally put in /private/etc/apache2/other and I call the file passenger.conf. I should note that this directory is owned by root, so when you create the file and save it you’ll have to provide your system password in order to make the changes.

Here is a sample of my configuration file:


LoadModule passenger_module /Users/carlos/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-2.2.14/ext/apache2/mod_passenger.so
PassengerRoot /Users/carlos/.rvm/gems/ree-1.8.7-2010.02/gems/passenger-2.2.14
PassengerRuby /Users/carlos/.rvm/bin/passenger_ruby

#Set the default environment to development
RailsEnv development

# Which directory do you want Apache to be able to look into for projects?
<Directory "/Users/carlos/work">
	Order allow,deny
	Allow from all
</Directory>

Finishing Up

If you’d like to make Ruby Enterprise Edition your default Ruby Interpreter, just use the following command:


rvm ree --default

Once Passenger has been configured, all that’s left to do is restart Apache. You can restart Apache by going to the System Preferences Pane and selecting the Sharing applet. Uncheck and re-check Web Sharing.

You should now be able to add Rails and Rack applications with the Passenger Preference Pane. Note: When opening the Passenger Preference Pane, you might see this warning:

Passenger Preference Pane 32bit Warning

This is normal if you have a 64-bit machine. Since RubyCocoa is 32-bit, it just has to relaunch the preference pane.

RVM is a fast moving target and as such these installation instructions may be out of date by the time you read them. I try to update my older posts when I get new information, but if you stumble across something that doesn’t work or if you know of a better way of doing something, please let me know.

Installing Rails 3 (beta 4) Using RVM

June 20, 2010 — 12 Comments

I’ve been collecting Rails 3 links ever since the first beta hit but I’ve been putting off installing it because I’ve been terribly busy and some of the early problems that I was reading on Twitter (namely with Bundler) turned me off.

Yesterday, I finally had enough time to start the installation and documentation process. For those following this guide, I should warn you in advance, Rails 3 is a fast moving target. Stuff is changing all the time, so by the time that you come across this guide it might be out of date or not The Rails Way of doing things.

I’ll try to keep it updated as best I can, but keep that warning in mind.

One more thing, the following should work with *nixes, but for those curious, I’m using OS X — Snow Leopard.

Note: Don’t prefix sudo when installing or uninstalling gems into an rvm’d environment.

Let’s get started by installing RVM first. There are many ways to install RVM, but I chose the gem method.

sudo gem install rvm

Once the gem has been installed run the install process.

rvm-install

This should install and configure it for your shell (it did for me), but if it doesn’t, refer to the RVM install documentation for setting up your shell correctly.

I found that the gem version was a version behind the head version, so I updated it using:

rvm update --head

Followed by:

rvm reload

From some of the links that I’ve been reading, it’s been suggested that you install Ruby 1.9.2 for use with Rails 3. Using RVM, this is easy to do:

rvm install 1.9.2-head

Installing and compiling Ruby 1.9.2 takes a while.

Switch over to the 1.9.2-head version and let’s setup a Rails 3 gemset:

rvm --create use 1.9.2-head@rails3

Install the pre-release of Rails 3:

gem install rails --pre

If everything has gone well we should be able to see beta 3 when running the rails —version command:


rails --version
Rails 3.0.0.beta4

Note: If you get a rails/cli error here it’s possible that you already have another beta version installed from somewhere. You can uninstall the previous beta gems, but it’s probably easier to just clean your gems instead:

gem clean

Note: This will only clean the gems in your rvm’d environment. It won’t affect any other Ruby/RubyGems install.

Since I use RSpec for my testing framework, I installed those gems:


gem install rspec --prerelease
gem install rspec-rails --prerelease

At this point, Rails should be installed and waiting for you to create a new project using:

rails new [path/project_name]

If you don’t specify a -d option to the rails command then it’ll use SQLite as the database, but you can always using the database of your choice:

rails new [path/project_name] -d mysql|postgres|sqlite3

Once you’ve created a project open it up in your editor of choice and familiarize yourself with the Gemfile file.

You should pay attention to the :require directive on gems. Sometimes the gem name and the library name aren’t the same. For example, here is the aws-s3 gem with its require line:

# gem 'aws-s3', :require => 'aws/s3'

If you want to install Rails Edge then comment out or delete the line from the Gemfile:

gem 'rails', '3.0.0.beta4'

And uncomment the line:

# gem 'rails', :git => 'git://github.com/rails/rails.git'

If you’re having weird issues with Rails 4, upgrading to Edge might be the way to go. I know that it fixes and error in a form bypassing validation in Rails3Beta2, so it might be worth it.

You should also note the database gem that’s listed in your Gemfile. In a simple project that I created it was listed as:

gem 'sqlite3-ruby', :require => 'sqlite3'

Since I installed RSpec and RSpec Rails, I should tell Bundler about them. Note that I’m only installing them in the test environment.

I added the following to the bottom of the Gemfile:


group :test do
  gem 'rspec', '>= 2.0.0.beta.12'
  gem 'rspec-rails', '>= 2.0.0.beta.12'
end

After you’ve edited your Gemfile to your liking, install them with Bundler:

bundle install

Once all of the gems have been installed, you should have a working Rails application that you can test by running:

rails server

If everything has gone according to plan you should have a working Rails3Beta4 app running.

Deploying to Heroku using Bundler with Named Groups

October 01, 2010 — 3 Comments

I recently ran into a problem deploying my blog app (Rails version 2.3.8) to Heroku when I switched to Bundler. I’ve separated my Gemfile into sections such as development and test. The theory here is that when an application is deployed into production, Bundler will ignore those gems and they won’t be installed on the production environment.

Since deploying to Heroku’s platform has been extremely painless ever since I switched to it, I figured using Bundler would equally painless. Unfortunately, I ran into some errors as it tried to install gems from my test environment into production. Normally, this would not be such a big deal, but in this case a few of my gems (namely autotest-growl and autotest-fsevent) are OS X specific and cannot be installed on the Heroku platform.

The error that was returned was similar to this one:


/usr/ruby1.8.7/lib/ruby/site_ruby/1.8/rubygems/installer.rb:482:in 
`build_extensions': ERROR: Failed to build gem native extension. (Gem::Installer::ExtensionBuildError) 

/usr/ruby1.8.7/bin/ruby extconf.rb 
extconf.rb:19: Only Darwin (Mac OS X) systems are supported (RuntimeError) 

Heroku’s official documentation states that they are aware of the issue and they are working with the Bundler team to get this out with Bundler’s 1.1 release. Unfortunately, that doesn’t help me (and I suspect others) now.

There are some hacks out there that some people have used successfully, but they all seemed, well like too much of a hack. I felt that there should be a better way.

Luckily, my good friend Matt Willhite (@MiWillhite) sent me a message that was passed onto him from Heroku Support. The trick is to add a configuration flag to Heroku with the following command:


heroku config:add BUNDLE_WITHOUT="development:test" --app app_name

Once I ran that command, I was able to deploy my application with Bundler behaving itself by installing only the gems that I needed.

Looks like the official Bundler documentation has been updated to include the suggested fix above.