views:

44

answers:

2

The rails app I have allows users to manage holiday homes. Each property has it's own "website/homepage" within my app and a user can tweak the content, it works well, quite pleased so far. Typical rails approach to the resources so the URLs to a particular property look like this for the "homepage" of a particular property.

localhost:3000/properties/1/

then

localhost:3000/properties/1/full_details
localhost:3000/properties/1/price_list

etc

Requirement is to map a domain name e.g. www.chalet-yeti.com and have it resolve (rewrite?) to localhost:3000/properties/1/

like so also...

www.chalet-yeti.com/full_details  -> localhost:3000/properties/1/full_details

The next user adds a property and I register a new name on their behalf and I'd like to do this of course..

www.apartment-marie.com  -> localhost:3000/properties/2/

Is this possible/advisable/doable in the same rails app? So far solutions have ranged from "why would you do that" to variations on "use mod_proxy / mod_rewrite / virtual_host config". In case it matters the app runs under apache and passenger on my server.

I don't want to pre-empt an answer but most people so far seem to point to apache configuration and most say what I'm attempting is not impossible / inadvisable. Really hope someone could at least point me in the right direction as I've been head scratching all morning. Out of my comfort zone here and I'm hoping I can launch my app and haven't spent six weeks building a white elephant! Unless I can do this URL thing, it's dead!

A: 

Within Rails, you should think of the requests coming just to a URI, without a host name section. That is, instead of localhost:3000/properties/1/full_details you need to think of /properties/1/full_details. The localhost:3000 part is just to get the request to Mongrel during the development process.

So what you really want is to take the request as it is received by the HTTPd (Apache, in your case) and extract some information to construct the request which is given to Rails.

mod_rewrite, which is an Apache module, is the sane way to do this.

You need to ensure that the same virtual host which runs your Rails application accepts requests for all the domain names you're using.

Then you can use mod_rewrite to do something like this:

RewriteCond %{HTTP_HOST} ^(www.)?chalet-yeti\.com$
RewriteRule ^(.*)$ /properties/1/$1 [L]

This will take every request to the host chalet-yeti.com (or www.chalet-yeti.com) and hand them to Rails as "/properties/1/$1" (where the $1 is any additional path, like full_details).

You'll need a block like that for each of your domains, but that's just two lines in your Apache configuration. Unless you're doing hundreds of domains, it should be tolerable, right?

pjmorse
despite the fact I can get a test rewrite rule to work, I can't get the rewriterule in your example to take - is just ignored. grrr.
Ahh, that's because I didn't edit my copy-paste properly. I had an extra `!` before the domain name, which meant it applied to all domains OTHER THAN the correct one. I've edited it now. Sorry.
pjmorse
OK, but *still* not operating - just does nothing, by that I mean I end up at the sites root URL. If I change the [L] to a [R] I end up in a redirect loop, but at least I guess the rules are being processed.
Right, [L] means "last rule." [R] sends a redirect back to the browser, which you don't want, because the next request will get redirected as well... endless loop.
pjmorse
+1  A: 

http://37signals.com/svn/posts/1512-how-to-do-basecamp-style-subdomains-in-rails

This is what you want. Don't mess with apache for that. It doesn't scale to hundreds of domains and it's prone to breakage.

epochwolf
I hear you, but I'm wondering *how* bad the apache approach is, I understand the apache config answer from pjmorse and it's definitely tolerable, very unlikely to be doing lots of domains.
This looks interesting but it's not quite what I'm trying to do and I still don't see the bit that tells the rails app to display www.mydomainname.com/full_details though rather than /localhost/properties/1/full_details
I think you're right that that's the most streamlined way to do it, but this application isn't expecting to get its arguments that way. Using this method requires the developer to be thinking about getting this data from the request from the beginning.
pjmorse
Correct, it requires designing the app around retrieving items by domain.
epochwolf