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.