Upgrading to Rails 3.1 on Heroku — Part I: Ruby 1.9.2

I am developing an application on Heroku’s Bamboo stack (bamboo-ree-1.8.7) that’s currently on Rails 3.0. I’d like to upgrade to Rails 3.1 to get the new asset pipeline working for me, but that, unfortunately, isn’t quite as easy as just updating my Gemfile. In this first part of the series I’ve documented the prerequisite steps by upgrading to Ruby 1.9.2 on my local machine.

Deep dependency chain

There’s a pretty deep chain of dependencies that I have to work out for this upgrade to go smoothly.

Rails 3.1 requires Heroku’s Cedar stack

First, Heroku only supports Rails 3.1 on the Cedar stack (well, technically, you can run Rails 3.1 on Bamboo but without the asset pipeline). Since I require the asset pipeline, I’ll have to migrate stacks

Cedar stack requires Ruby 1.9.2

The Cedar stack only offers Ruby MRI 1.9.2, and my current Bamboo stack is still on REE 1.8.7. In addition, I am still using the default Ruby included with OS X Snow Leopard.

Eos:~ jcarlson$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
Eos:~ jcarlson$ 

Heroku also strongly recommends that applications still on bamboo-ree-1.8.7, like mine, first upgrade to bamboo-mri-1.9.2 to ensure compatibility. So this means I’ll need to upgrade my local Ruby version to 1.9.2 as well.

I have other Rails applications

I have at least one other Rails application I am actively developing that is still using Ruby 1.8.7. I would upgrade it as well, but Dreamhost only currently supports Ruby 1.8.7.

[fay]$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [x86_64-linux]
[fay]$ 

I might consider moving that application to Heroku, but that is outside the scope of what I want to accomplish today. I am using shared Apache/Passenger stack to serve my Rails application on Dreamhost (and locally in development) which, unfortunately, means I cannot choose or upgrade the Ruby version myself on Dreamhost. Passenger also only allows one version of Ruby for all of the applications it serves, which is a bummer.

Step One: Resolving Ruby versions with RVM

To address the ‘multiple rubies’ problem, I’m going to try using RVM to manage my Ruby binaries. According to the documentation, this should let me use Ruby 1.9.2 with my Heroku-deployed app, Ruby 1.8.7 with my Dreamhost-deployed app, and the default system Ruby everywhere else.

I’ll defer to the official installation instructions, rather than repeat them here. I originally did the multi-user installation thinking I would probably want to use the installed rubies with Apache/Passenger, and I don’t want servers referencing Ruby installations in my home directory. However, as I progressed through the rest of these instructions, the multi-user mode became difficult to work with, so I rvm imploded it and will address server rubies later on.

I installed ree-1.8.7 for my Dreamhost applications. RVM doesn’t seem to have a -p72 version of ree-1.8.7, so -head will have to do. This takes a while.

Eos:~ jcarlson$ rvm install ree-1.8.7-head

I couldn’t tell exactly what patch level Heroku runs for their bamboo-mri-1.9.2 or cedar stacks, so I’ll go with -head again. And again we’ll wait.

Eos:~ jcarlson$ rvm install ruby-1.9.2-head

Step Two: Configure per-project .rvmrc

To make development (hopefully) simpler, I’m going to use the project-specific .rvmrc file to store Ruby version settings. I’m also using git-flow, so I’ll first setup a support branch to isolate any changes to my code before proceeding.

Eos:Projects jcarlson$ ruby -v
ruby 1.8.7 (2009-06-12 patchlevel 174) [universal-darwin10.0]
Eos:production-hub jcarlson$ rvm --rvmrc --create ruby-1.9.2-head@production-hub
Eos:production-hub jcarlson$ cd ..; cd production-hub
Eos:production-hub jcarlson$ ruby -v
ruby 1.9.2p312 (2011-08-11 revision 32926) [x86_64-darwin10.8.0]

So, hooray, my project now automatically uses Ruby 1.9.2 from the command line. RVM recommends adding the .rvmrc file to source control, so be sure to do so, especially if you’re sharing code with collaborators.

One other gotcha — with a per-project .rvmrc, and the per-project gemset we created along with the .rvmrc file, RVM will actually set BUNDLE_PATH automatically. This means we’ll need to bundle install after setting up our gemset for the first time.

Eos:production-hub jcarlson$ bundle install
...
Your bundle is complete! Use `bundle show [gemname]` to see where a bundled gem is installed.
Eos:production-hub jcarlson$

Testing

While running the application locally using rails server to ensure compatibility, I noticed a small problem with a big impact: Date parsing. Under Ruby 1.8.7, Date.parse will handle ambiguous as best as possible. Under 1.9.2, though, the ambiguity has been tossed out. This meant that some of my form fields using jQuery UI’s datepicker had to have their formats updated so they worked with a date format that wasn’t ambiguous.

Conclusion

That was pretty much it to get Ruby 1.9.2 installed for one project and keep Ruby 1.8.7 for the other. It didn’t take too long and it wasn’t painful.

I’ll still need to configure my Apache/Passenger server to use Ruby 1.9.2 and then test that everything works, but since Heroku recommends using Thin on the Cedar stack and doesn’t use Passenger or Apache, it might be time to revise my local development setup. I’ll save that for later and just use rails server for local testing right now.

Leave a Reply

Your email address will not be published. Required fields are marked *