Rails 路由在单个应用程序上处理多个域

我一直无法找到一个可行的解决这个问题的办法,尽管这里和其他地方有几个类似的问题。Rails 3似乎还没有回答这个问题,所以我们来看看:

我有一个应用程序,目前允许用户创建自己的子域,其中包含他们的应用程序实例。在 Rails2中,最好使用子域 fu gem,而在版本3中,它极其简单,如 Railscast —— http://railscasts.com/episodes/221-subdomains-in-rails-3所示。

这是很好的东西,但是我也想提供一个选项,让用户把他们自己的域名和他们的帐户关联起来。因此,虽然他们可能有 http://userx.mydomain.com,我希望他们选择有 http://userx.com关联以及。

我在 Rails 2中发现了一些关于这样做的参考资料,但是那些技术似乎不再起作用了(特别是这个: https://feefighters.com/blog/hosting-multiple-domains-from-a-single-rails-app/)。

有人能推荐一种使用路由接受任意域并将其传递给控制器的方法吗? 这样我就可以显示适当的内容了?

更新 : 现在我已经得到了大部分的答案,感谢 Leonid 及时的响应,以及对代码的全新看法。它最终需要对我正在使用的现有子域代码(来自 Railscast 解决方案)进行添加,然后再添加一点到 routues.rb。我还没有完全做到这一点,但是我想把我目前所做的发布出来。

在 lib/subdomain.rb:

class Subdomain
def self.matches?(request)
request.subdomain.present? && request.subdomain != "www"
end
end


class Domain
def self.matches?(request)
request.domain.present? && request.domain != "mydomain.com"
end
end

我已经添加了第二个类模仿第一个类,这就是已知的工作。我只是添加了一个条件,以确保传入的域不是我托管主站点的域。

Rb 中使用了这个类:

require 'subdomain'
constraints(Domain) do
match '/' => 'blogs#show'
end


constraints(Subdomain) do
match '/' => 'blogs#show'
end

在这里,我用一个片段预先准备现有的子域代码(同样,它工作得很好)来检查域。如果此服务器响应该域,而它不是主站点操作的域,则转发到指定的控制器。

虽然这看起来起作用了,但是我还没有完全解决这个问题,但是我认为这个问题已经解决了。

41628 次浏览

It's actually simpler in Rails 3, as per http://guides.rubyonrails.org/routing.html#advanced-constraints:

1) define a custom constraint class in lib/domain_constraint.rb:

class DomainConstraint
def initialize(domain)
@domains = [domain].flatten
end


def matches?(request)
@domains.include? request.domain
end
end

2) use the class in your routes with the new block syntax

constraints DomainConstraint.new('mydomain.com') do
root :to => 'mydomain#index'
end


root :to => 'main#index'

or the old-fashioned option syntax

root :to => 'mydomain#index', :constraints => DomainConstraint.new('mydomain.com')

In Rails 5, you can simply do this in your routes:

constraints subdomain: 'blogs' do
match '/' => 'blogs#show'
end