views:

1473

answers:

6

Using Morph Labs' Appspace to deploy a site means no automated way to redirect 'myapp.com' to 'www.myapp.com' (and no access to .htacess).

Is there an in-rails way to do this? Would I need a plugin like subdomain-fu?

More specifically, I'm trying to do something like:

  • 'myapp.com' => 'www.myapp.com'
  • 'myapp.com/session/new' => 'www.myapp.com/session/new'

Basically, I always want the 'www' subdomain prepended on every request (because the SSL cert specifically has a common name of 'www.myapp.com').

+1  A: 

Here is a couple of different ways:

 head :moved_permanently, :location => ‘http://www.newdomain.com’

another:

def rails_301
headers["Status"] = "301 Moved Permanently"
redirect_to "http://www.newdomain.com"
end
smazurov
I just edited my original question to give more detail on what I'm trying to accomplish. Does your answer still apply?
Allan L.
not sure, I'm afraid you'd have to try it :)
smazurov
+15  A: 

Maybe something like this would do the trick:

class ApplicationController < ActionController::Base
  before_filter :check_uri

  def check_uri
    redirect_to request.protocol + "www." + request.host_with_port + request.request_uri if !/^www/.match(request.host)
  end
end
carson
Looks sweet, I'm gonna give this a try on the next deploy and report back on the results!
Allan L.
Carson, this worked for me. Thank you very much for your answer!
Allan L.
Carson, I apologize for not marking your answer as the answer I accepted previously.I didn't realize all I had to do was click on the check mark.Again, my apologies.
Allan L.
This is a great use case for a Rack middleware though. You can get some ideas from this one: http://coderack.org/users/jtrupiano/entries/37-rackrewrite
hgimenez
MAKE SURE TO PUT THE CHECK_URI AS THE FIRST BEFORE FILTER. I have recently run into several very difficult problem to track down in my app, and they all resulted from logged_in checks occuring before the check_uri call.
Mike H
Great code! This worked perfect!
CalebHC
hgimenez is absolutely correct that a rack middleware is perfect for this situation. The link he gives returns a 404 now, but the same site has a middleware called "Force Domain" that likely replaced initial middleware hgimenez linked to.
Scott S.
+3  A: 

Carson's answer works great.

Here's the code to go the other way (www -> no www)

before_filter :check_uri

def check_uri
  if /^www/.match(request.host)
    redirect_to request.protocol + request.host_with_port[4..-1] + request.request_uri 
  end
end
Mike H
A: 

Thanks for that! I was trying heroku's "ensure domain filter" with no success, this is much cleaner and it works for me.

Thiago Ganzarolli
A: 

This worked great for me. I did make one small addition as I only wanted this behavior in my production environment:

def check_uri
  redirect_to request.protocol + "www." + request.host_with_port + request.request_uri if !/^www/.match(request.host) if Rails.env == 'production'
end
levi rosol
A: 

I know this is answered, but I thought everyone else should know about the CodeRack: Canonical Host solution. This is really nice as it allows for env specific redirects. http://coderack.org/users/tylerhunt/middlewares/6-canonical-host

erskingardner