尽管这里和其他地方有几个类似的问题,但我一直无法找到解决此问题的可行解决方案。这个问题似乎在 Rails 3 中还没有得到解答,所以这里是:
我有一个应用程序,当前允许用户创建自己的子域,其中包含他们的应用程序实例。在 Rails 2 中,您最好使用 subdomain-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 解决方案),然后添加一些到 paths.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
我添加了第二个类来模仿第一个类,这是众所周知的工作。我只是添加一个条件,确保传入域不是我托管主站点的域。
这个类用在routes.rb中:
require 'subdomain'
constraints(Domain) do
match '/' => 'blogs#show'
end
constraints(Subdomain) do
match '/' => 'blogs#show'
end
在这里,我在现有的子域代码(同样,它工作正常)前面加上一个节来检查域。如果该服务器响应该域,但它不是主站点运行的域,则转发到指定的控制器。
虽然这似乎有效,但我还没有完全解决整个问题,但我认为这个特定问题已经解决了。
Rails 3 实际上更简单,根据 http://guides.rubyonrails.org/routing.html#advanced-constraints:
1)在
lib/domain_constraint.rb
中定义自定义约束类:
class DomainConstraint
def initialize(domain)
@domains = [domain].flatten
end
def matches?(request)
@domains.include? request.domain
end
end
2)使用新的块语法在路由中使用该类
constraints DomainConstraint.new('mydomain.com') do
root :to => 'mydomain#index'
end
root :to => 'main#index'
或者老式的选项语法
root :to => 'mydomain#index', :constraints => DomainConstraint.new('mydomain.com')
在 Rails 5 中,您可以在路线中简单地执行此操作:
constraints subdomain: 'blogs' do
match '/' => 'blogs#show'
end
要扩展@user3033467答案,您不限于子域。
根据文档:
对于我的具体情况,我需要“域”和“子域”的约束。
所以这对我有用:
constraints host: %w[domain.com] do
end
对于子域:
constraints subdomain: %w[subdomain www-subdomain] do
end
您甚至可以指定端口。
constraints subdomain: %w[subdomain www-subdomain], ports: 3000 do
end
为了将来参考,这是您可以传入的完整列表: