Updating to Rails 3.1


Updated February 17, 2013.
TODO:
* asset pipeline creates sandbox for each //= require; sass variables don’t hold outside sandbox. Use .css.scss with `@import ‘file.css’;` to circumvent.
* stylesheet_link_tag adjustment
* FactoryGirl notes
* Switching to haml: $ for e in *.erb; do html2haml -e $e ${e%.erb}.haml; done
* .gitignore .sass-cache
* Capybara 2 great heartache

Should you update to Rails 3.1 or not? Isn’t it too complicated? Won’t it break everything?

Good questions.

Ultimately, deciding when to upgrade is a business decision.

As it turns out, despite the amount of noise, upgrading to Rails 3.1 isn’t very difficult.

Update everything else first

Before digging into a Rails 3.1 upgrade, ensure your application is working correctly in your current environment. This could be the right time to update your testing gems, and anything else you would normally do for normal application maintenance. Get that regular stuff out of the way first.

Specifically, if you’re running plain-Jane UJS with the Prototype library, consider moving to jQuery first. It will make asset migration much easier once you set up Rails 3.1. The biggest hurdle for most Rails developers seems to be how much of the Prototype library their applications are using.

Given an app already working with Rails-native jQuery, updating Rails 3 to Rails 3.1 is not difficult, but it can be made easier than not. Here are a list of things of things to watch out for:

  1. First, and this is important, create and switch to a dedicated gemset for the existing Rails 3 application. For example, rvm use 1.9.3@myapp_r3 --create.
  2. You may also want to create a branch for this cleanup work.
  3. Take this opportunity to clean up your existing Gemfile. Remove any unneeded gems, then remove Gemfile.lock.
  4. Install Bundler for this gemset: gem install bundler.
  5. bundle install gets you a nice, clean current Rails 3 installation.
  6. Ensure everything runs correctly, tests pass with no deprecation warnings, you know the drill.
  7. You should probably commit here.
  8. If you created a branch for cleanup, consider merging back into master as well.

This gives you a clean, fresh Rails 3 source tree to start from.

You might also want to lock important gems such as cucumber-rails and rspec-rails at their current version numbers, to ease the transition to Rails 3.1. Fight one battle at a time, as they say. This way you don’t end up in a bind with testing gems such as Cucumber and RSpec vomiting all over your nice update.

Technically, it’s not likely necessary to switch to jQuery from Prototype right now either. The upgrade should work almost as easily.

Rails 3.1 really fast

First create dedicated gemset and branch, then build the gemset from scratch with only what you need:

  1. Make a Rails 3.1: branch: git branch -a myapp_r3.1.
  2. And its corresponding gemset: rvm use 1.9.2@myapp_r3 --create.
  3. IMPORTANT: rm Gemfile.lock
  4. Add the Rails 3.1 version number. At the time this was written (July 2, 2011): gem 'rails', '3.1.0.rc4'.
  5. gem install bundler
  6. bundle install
  7. It doesn’t hurt to examine Gemfile.lock to see you really are using Rails 3.1
  8. Comment out config.action_view.debug_rjs = true in config/environments/development.rb.
  9. At this point, your application should just run.

Now run all your tests, make sure everything works correctly. It might be helpful to lock your testing gems in your Gemfile at their current, working version number.

And this is a great place to make your first commit on your Rails 3.1 branch.

Upgrading your configuration

Rails 3.1 considerably simplifies the config/boot.rb file:


require 'rubygems' # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])

Simple. Commit it.

Perhaps for you that will be enough for now. But Rails 3.1 has some very interesting new features with respect to the asset pipeline, so let’s take a look at that next.

Building the asset pipeline

By now, you might be mildly surprised to realize that upgrading to 3.1 can be as simple as changing the Rails version in the Gemfile, and commenting out the debug_ujs in the development.rb file. All this gemset and branching machinery seems a bit overblown for such a simple task.

But the new asset pipeline will considerably clean up your application. There are three steps to it:

  1. Moving assets into the pipeline, and
  2. Updating style and javascript tags in application.rb.
  3. Upgrading the pipeline to use the latest cool tools.

Step 2 is optional.

Step 1: Moving assets to the pipeline

Rails 3.1 assets are CSS files, Javascript files and the like. Basically, everything which used to be delivered from public is now delivered from app/asset using RSM the (Rails Standard Magic) you already know and love.


mkdir app/assets git mv public/images app/assets git mv public/javascripts app/assets git mv public/stylesheets app/assets

Step 2: Update application.rb

Now add the following to config/application.rb:

# Enable the asset pipeline
config.assets.enabled = true

Change all the images paths from images to assets: s/images/assets.

Fire up Rails and again, everything should “just work.”

This would be another great place to commit on the 3.1 branch.

Javascript manifest app/assets/javascripts/application.js:

//= require jquery
//= require jquery_ujs
//= require_tree .

(Note comment about jquery_rjs/jquery_ujs below.)

Alternatively, insteading of using require_tree ., you can add individual files as necessary.

Stylesheet manifest app/assets/stylesheets/application.css:

/*
 *= require_self
 *= require_tree . 
*/

Again, add individual files in lieu of adding the entire directory tree.

Step 3: Cool new tools

Coffee script. Uglifier. Sass.

I’m not currently using Coffee script. But I will be soon. It uses my favorite operator: ->.

There has been some controversy about this (and other Coffee script conventions), but it makes sense to me as Ruby 1.9 introduces -> to parameterize blocks. Sweet!

As per David Rice’s instructions, add the following to your Gemfile to build Rails 3.1 asset pipeline:

gem 'rails', '3.1.11'
.
.
.
# Rails 3.1 - Asset Pipeline
group :assets do
  gem 'sass-rails'
  gem 'coffee-script'
  gem 'uglifier'
end
.
.

As usual, bundle install.

Finishing up

Depending on your application size, user base, etc, you may or may not want to clean everything up after your update. If so, it’s the easy standard stuff:

  1. Make your final 3.1 commit.
  2. git checkout master
  3. git merge rails3.1
  4. git branch -D rails3.1
  5. rvm gemset delete myapp_r3

Or not.

Quick recap of relevant commits

To make it easy to read and understand your commits, update to Rails 3.1 in the following order:

  1. Update current Rails 3. Switch to jQuery now if you can.
  2. Clean up your gems and commit a known working Gemfile.lock
  3. Create a 3.1 gemset and a 3.1 branch, update Rails itself and get it running.

  4. Move /images to /assets

  5. Move /stylesheets to /assets
  6. Move javascripts to /asset
  7. Move any static pages necessary for application to /assets.
  8. After updating files in /config/
  9. After updating files in /app

If you follow this order of operations, you will get a very clean set of commits along your upgrade branch.

If you don’t, you’re going to get a few massive commits with a lot of different types of files mixed together. Annoying, and makes it hard to fire up gitx (or your favorite diffing application) and see what you did. And you might want to see what you did for this update when you do the next one. So keep the commits focused.

Related links for updating to Rails 3.1

Here’s the best I could find, with the leading link to Delicious (updated October 15, 2011):

Comments are open, would love to hear whether this did or did not work for you.

This entry was posted in rails and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

7 Comments

  1. eml
    Posted July 12, 2011 at 3:27 am | Permalink

    We’re using Rails 3.1.0-rc4 for our project and things are going smoothly. I spotted a little error in one of your Gemfiles: gem ‘rails’, ’3.1.0.cr4′ # soon to be unnecessary <- should be rc4, not cr4.

    Cheers
    – eml

    • Posted July 12, 2011 at 7:07 am | Permalink

      Fixed. I would *never* have caught that!

  2. Posted July 13, 2011 at 7:34 pm | Permalink

    What a great post! Thanks!

  3. Posted July 13, 2011 at 7:38 pm | Permalink

    forgot to mention that will_paginate users can use a temporary solution :
    edit the Gemfile like this
    gem ‘will_paginate’, :git => ‘https://github.com/wantful/will_paginate.git’

  4. Michèle Garoche
    Posted July 13, 2011 at 10:19 pm | Permalink

    Absolutely great, a little less than two hours to upgrade to 3.1.rc4.

    I’ve just noted that there is a little typo in the first sentence of Building the asset pipeline section:
    commenting out the debug_ujs..
    instead of:
    commenting out the debug_rjs… (notice rjs, not ujs)

    Thanks for the great post.

    • Posted July 13, 2011 at 10:24 pm | Permalink

      Noted. Will update on next pass through the material, and put a note in the article right now.

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>


dool.in