It is a simple issue, but I can't seem to find an answer doing some quick googling.
What's the Ruby on Rails way of doing this 301 direct (http://x.com/abc > http://www.x.com/abc). A before_filter
?
For example, if you've chosen to use non-www URLs as the canonical type, you should redirect all www URLs to their equivalent URL without the www. Example: A server receives a request for http://www.example.org/whaddup (when the canonical domain is example.org)
For rails 4, use it -
before_filter :add_www_subdomain
private
def add_www_subdomain
unless /^www/.match(request.host)
redirect_to("#{request.protocol}www.#{request.host_with_port}",status: 301)
end
end
Ideally you'd do this in your web server (Apache, nginx etc.) configuation so that the request doesn't even touch Rails at all.
Add the following before_filter
to your ApplicationController
:
class ApplicationController < ActionController::Base
before_filter :add_www_subdomain
private
def add_www_subdomain
unless /^www/.match(request.host)
redirect_to("#{request.protocol}x.com#{request.request_uri}",
:status => 301)
end
end
end
If you did want to do the redirect using Apache, you could use this:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^www\.x\.com [NC]
RewriteRule ^(.*)$ http://www.x.com/$1 [R=301,L]
An alternative solution might be to use the rack-canonical-host gem, which has a lot of additional flexibility. Adding a line to config.ru:
use Rack::CanonicalHost, 'www.example.com', if: 'example.com'
will redirect to www.example.com only if the host matches example.com. Lots of other examples in the github README.
While John's answer is perfectly fine, if you are using Rails >= 2.3 I would suggest to create a new Metal. Rails Metals are more efficient and they offers better performance.
$ ruby script/generate metal NotWwwToWww
Then open the file and paste the following code.
# Allow the metal piece to run in isolation
require(File.dirname(__FILE__) + "/../../config/environment") unless defined?(Rails)
class NotWwwToWww
def self.call(env)
if env["HTTP_HOST"] != 'www.example.org'
[301, {"Content-Type" => "text/html", "Location" => "www.#{env["HTTP_HOST"]}"}, ["Redirecting..."]]
else
[404, {"Content-Type" => "text/html"}, ["Not Found"]]
end
end
end
Of course, you can customize further the Metal.
If you want to use Apache, here's a few configurations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With