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


90

尽管这里和其他地方有几个类似的问题,但我一直无法找到可行的解决方案。对于Rails 3,似乎没有回答这个问题,所以可以这样:

我有一个当前允许用户创建包含其应用程序实例的子域的应用程序。在Rails 2中,最好使用subdomain-fu gem来提供服务,而在Railscast中,根据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解决方案)进行添加,然后在route.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

在这里,我将在现有子域代码(再次可以正常工作)的前面加上节来检查域。如果此服务器响应该域,而不是主站点运行所在的域,请转发到指定的控制器。

尽管这似乎可行,但我还没有完全解决整个问题,但是我认为这个特殊问题已经解决了。


1
非常感谢您的编辑,Aaron。我现在正在处理完全相同的情况。作为后续问题,您如何使服务器接受正在转发到它的任何域?我认为这是.conf文件中的设置,但是我不确定。任何帮助,将不胜感激!
时分

亚伦,我和你在一起。我想做同样的事情。但是我不想对域进行硬编码。我希望所有这些均以编程方式完成,而无需区域文件和Web服务器重新启动。
Michael K Madison

1
迈克尔,您需要解决这个问题。使用主机或子域约束明确声明和硬编码专用于您的应用程序的路由(例如,注册),然后将主路由视为“任何域或子域”。然后,控制器的职责是查找当前域或子域并将其映射到合适的客户。
贾斯汀·法兰西

Answers:


95

根据http://guides.rubyonrails.org/routing.html#advanced-constraints,它实际上在Rails 3中更简单:

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')

6
这个答案对我来说似乎简单得多。
杰瑞德

7
这是一个很好的解决方案。在开发环境中如何工作?
superluminary 2012年

2
@superluminary如果您设置要开发的本地域(例如,通过/etc/hosts),则可以完美地工作。
Leonid Shevtsov 2012年

7
注意:如果您在本地使用Pow并拥有mydomain.com.dev,则request.domain返回.com.dev。更改request.domainrequest.host,即可正常使用。
Eric Muyser 2013年

2
我发现必须为此创建未命名的路由,否则我会收到Invalid route name, already in use: 'root'错误信息……为此,我将路由更改为root :to => 'mydomain#index', as: nil
Just Lucky真的

5

在Rails 5中,您只需在路线中执行以下操作:

constraints subdomain: 'blogs' do
  match '/' => 'blogs#show'
end
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.