:requirements Method for Rails 3 Routes

In Rails 2, if you wanted to have a parameter on a URL that had a period (e.g. a decimal point in latitude/longitude coordinates), you needed to use the :requirements method to tell Rails to include everything in the URL.

e.g.if your URL was /spots/new_popup/37.77617617425586,-122.39735126495361

… then the Rails 2 route would look like this:

map.connect '/spots/new_popup/:coords', :requirements => {:coords => /.*/}, :controller => 'spots', :action => 'new_popup'

In Rails 3, there :requirements method has been replaced with :constraints. So the route above would be re-written like this:

match '/spots/new_popup/:coords', :constraints => {:coords => /.*/}, :controller => 'spots', :action => 'new_popup'

FileColumn to Paperclip Migration

Like so many people, when moving from Rails 2 to Rails 3, I found myself migrating from using FileColumn (i.e. file_column) to Paperclip, for image-upload handling in rails. I found an excellent migration guide written by Mark Cornick.

The general process is:

  1. Install Paperclip.
  2. Generate a migration to add the Paperclip-controlled image to your model. This adds a few Paperclip columns to the model’s table.
  3. Update your model code to use Paperclip.
  4. Update your views to use Paperclip’s method for writing the images, and Paperclip’s method for writing the fields for uploading the images.
  5. Write a migration that does the leg-work of moving your images from FileColumn to Paperclip.
  6. Uninstall FileColumn.

Step #5 is the most complex bit. There’s a few things that your migration has to do:

  1. Rename/restructure directories where FileColumn stored images to the new Paperclip way. e.g. directory names are singular in FileColumn, plural in Paperclip.
  2. Rename/move actual images to the new Paperclip-expected locations. e.g. different image styles (e.g. original, thumbnail, etc.) differ between FileColumn and Paperclip.
  3. Populate the new Paperclip table columns with data about the images.

Mark shared a Gist that showed did all these, except for a couple of issues: It didn’t handle varying image styles (e.g. original, thumbnail, etc.), and it wasn’t a reversible migration. Using Mark’s migration as a starting point, I added support for styles, and made it reversible*. You can see my fork as a Gist. I hope someone finds it useful.

* The “reversible” comes with caveats: I’ve tried to write it in such a way that it will recover from a failed forward migration, but testing rolling back from every possible point of failure would be onerous. It works reliably if the whole forward migration succeeds, and the resulting DB contents and file structure match the beginning point. Empty Paperclip directories are not deleted after rolling back. You should back-up your database before trying it.

Installing RMagick on Cygwin

RMagick is a Ruby to ImageMagick framework that’s needed if you want to edit images using Rails. FileColumn, a Rails plugin for handling file uploads, plugs into RMagick very smoothly. While FileColumn is really simple to use, installing RMagick on Cygwin seemed really daunting. There were a bunch of warnings on how it differs from a usual Rails plugin install. So I’m summarizing my experience here:

  1. First install ImageMagick for Cygwin. Do this by updating Cygwin itself, using the Cygwin setup program. It’s the same approach as you use for installing Cygwin the first time around. When you get to the Select Packages page, find the ImageMagick packages under the Graphics node and make sure they’re set to be installed. Look for libImageMagick1; there are a few others.
  2. Run gem update –system
  3. Download the RMagick gem for Linux. Not the Win32 one. That’s the one called “rmagick”. You have to download it; you can’t install it remotely.
  4. From the directory where you downloaded the RMagick gem, run gem install rmagick –local
  5. Rebase Cygwin. I’ve never had to do this before, but I got a bunch of errors in the Ruby server output console saying the following when RMagick was used:
    unable to remap C:\cygwin\usr\X11R6\bin\cygXext-6.dll to same address ruby died waiting for dll loading, errno 11
    To rebase Cygwin, close all your Cygwin shells, and open an ash shell by going to Start>Run…, then enter C:\cygwin\bin\ash.exe in the Run dialog and click OK. Run /bin/rebaseall from the ash console.

Then restart the Rails server from script.

For reference, I used RMagick 2.5.2, with Ruby 1.8.2 and Rails 2.1.0.