Camel Punch - Brighton-based web development

301 redirect with Rails

What a 301 Redirect is

301 'moved permanently' redirects are a useful, search engine friendly way to move your visitors from an outdated address to an up-to-date one. This page, for example, used to live on www.andrewbruce.net, but now lives here on the Camel Punch site. To manage that change, the andrewbruce.net page redirects visitors to this page.

Approach 1

This approach allows you to easily redirect users to another place on the web from any controller action.

Simply use the standard action redirect with the :status option, like so:

class SomeController < ApplicationController
  def show
    # your code goes here
    redirect_to 'http://some-other.place/on/the/web', :status => :moved_permanently 
  end
end

You should always check the appropriate section in the Rails API. For redirects, you want redirect_to from ActionController::Base. If you know the name of the method you want to use (half the battle with learning Rails), just visit api.rubyonrails.org and use your browser's search functionality to find the method.

Approach 2: use config/routes.rb

Rails 3 allows you to easily create 301 redirects directly from the routes config file:

match "/old-path", :to => redirect("/new-path")

Approach for older versions of Rails

This is the version I used to use on an older site I ran. It lets you manage multiple missing pages easily, using a style similar to Approach 2. I've updated it for Rails 2.3.x.

The Controller

Create a new controller under, for example:

app/controllers/redirect_controller.rb

The contents of that file should be:

class RedirectController < ApplicationController
  def index
    if params[:url]
      redirect_to params[:url], :status => :moved_permanently
    else
      redirect_to :root, :status => :moved_permanently
    end
  end
end

The Config

That's step 1. Now for each redirected page, add an entry within your config/routes.rb add a line similar to the following:

map.connect '/old_page_that_used_html_suffix.html', :controller => 'redirect', :url => '/path/to/new_page_that_does_not'

Step 2 of 2 complete.

You may have noticed that if there is no path sent to the redirect index action, then the visitor is redirected to the site's home page. This allows you to do the following for pages that you know do not exist, but you do not want to appear as 404s (you'd prefer the visitors to be directed to the home page):

map.connect '/old_file_to_be_dropped.html', :controller => 'redirect'

Further reading

You may wish to see the definition of the 301 status code at w3.org.

About the author

This tutorial's author is Andrew Bruce, who writes:

This was the most frequently requested entry in my now defunct blog, so I've moved it here and updated it for newer versions of Rails.