Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails 3 routing and multiple domains

My app allows people to create portfolios. I would like for them to be able to connect their domain to their portfolio.

So somedomain.com would show /portfolio/12, someotherdomain.com would show /portfolio/13 and so on. But I don't want the redirect. I want the user to see somedomain.com in the browser url.

How do I do that?

Ok, I've found this solution:

match "/" => "portfolio#show", 
  :constraints => { :domain => "somedomain.com" }, 
  :defaults => { :id => '1' }

As I don't have many custom domains, this is fine for now but the question is - how to make this dynamic, to read domain and id data from db?

like image 714
Peter Koman Avatar asked May 19 '11 06:05

Peter Koman


2 Answers

Ok, let's assume you own yourdomain.com and use it as your home page for your application. And any other domain name like somedomain.net is mapped to a portfolio page.

First of all, in your routes.rb you need to catch yourdomain.com and map it to wherever your home page is, so that it stands out from the rest of the crowd.

root :to => "static#home", :constraints => { :domain => "yourdomain.com" }

Then you need to catch any other root on any domain and forward it to your PortfoliosController

root :to => "portfolios#show"

Keep in mind that this line will only be checked if the previous line fails to match.

Then in your PortfoliosController find the requested portfolio by its domain rather than id.

def show
  @portfolio = Portfolio.find_by_domain(request.host)
  …
end

Of course you may want to rescue from an ActiveRecord::RecordNotFound exception in case the domain is not in your database, but let's leave that for another discussion.

Hope this helps.

like image 97
edgerunner Avatar answered Oct 21 '22 19:10

edgerunner


First, you should add a field to the portfolio model to hold the user's domain. Make sure this field is unique. Adding an index to the field in your database would also be wise.

Second, set your root to route to the portfolios#show action, as you already did, but without the constraints.

Then, in the PortfoliosController#show method, do the following check:

if params[:id]
  @portfolio = Portfolio.find(params[:id])
else
  @portfolio = Portfolio.find_by_domain(request.host)
end

After this, the only thing left to do is to make sure your own domain does not trigger the portfolio#show action. This can be done with the constraint you used before, but now with your own domain. Be sure to put this line in routes.rb above the line for the portfolio#show action, since the priority is based upon order of creation.

like image 44
Kris Avatar answered Oct 21 '22 19:10

Kris