问题
I have a Rails 3 application, say, with hotels, where hotels belong to parent areas. When a user hits the app (served by mongrel >> nginx), I want the domain name used in the request to decide what area of hotels to serve up (domain name >> area). To achieve this I can see two options:
1) Rewrite the URL with nginx, inserting the area id after the domain name (e.g. birminghamhotels.co.uk => proxy_pass http://myupstream/areas/3$request_uri).
Benefits: Domain to object mapping happens where accepted domains are defined: nginx.conf. Should be transparent to users (pretty URLs possible as they are rewritten).
Drawbacks: Breaks Rails url helpers, no more link_to or form_for. Hard-coded object reference is naughty.
2) Catch the domain name in routes.rb and look up the Area via a unique "domain" attribute for each Area (or even a has_many if you fancy).
Benefits: Should allow use of all Rails URL helpers. Requested domain linked directly to resource so exceptions can be handled.
Drawbacks: Without rewriting URLs with nginx, wouldn't users see: birminghamhotels.co.uk/areas/3/hotels/42 instead of just birminghamhotels.co.uk/hotels/42? Also, I don't have a clue how to do it!
So, I've tried option #1 but ran into trouble with URL helpers etc. I've tried to come up with a way of trying option #2 but haven't been able to suss the correct syntax despite a lot of ogling. Now the fact I cannot find any answers by searching makes me think I got the wrong end of this problem. Is there a third option? How would you solve it?
Oh and btw, I am not building another hotel listing website - plenty enough of those around already. Just happened to be a close enough example.
回答1:
Assuming each area has some sort of domain_name field, it seems like you should be able to do something like this:
class HotelsController < ApplicationController
def index
@hotels = Area.find_by_domain_name(request.subdomains.first).hotels
end
end
You could even refactor it into a named_scope using a lambda if you like.
来源:https://stackoverflow.com/questions/3323643/rails-route-to-model-instance-by-domain-name