【问题标题】:Rails routing to handle multiple domains on single applicationRails 路由在单个应用程序上处理多个域
【发布时间】:2011-05-11 14:17:39
【问题描述】:

尽管这里和其他地方有几个类似的问题,但我一直无法找到解决这个问题的可行方法。 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 解决方案),然后在 routes.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

在这里,我在现有的子域代码(同样,它工作正常)前面加上一个节来检查域。如果此服务器响应该域并且它不是主站点运行的域,则转发到指定的控制器。

虽然这似乎有效,但我还没有完全完成整个工作,但我认为这个特殊问题已经解决了。

【问题讨论】:

  • 非常感谢您的编辑,亚伦。我现在正在处理完全相同的情况。作为一个后续问题,您如何让您的服务器接受转发给它的任何域?我认为这将是 .conf 文件中的设置,但我不确定是什么。任何帮助将不胜感激!
  • 亚伦,我和你在一起。我想做同样的事情。但我不想对域进行硬编码。我希望这一切都以编程方式完成,无需区域文件和网络服务器重新启动。
  • 迈克尔,你需要解决这个问题。使用主机或子域约束显式声明和硬编码专用于您的应用程序(例如注册)的路由,然后将您的主路由视为“任何域或子域”。然后,您的控制器负责查找当前域或子域并将其映射到正确的客户。

标签: ruby-on-rails ruby-on-rails-3 routing routes subdomain


【解决方案1】:

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

【讨论】:

  • This answer 对我来说似乎要简单得多。
  • 这是一个很好的解决方案。它如何与开发环境一起工作?
  • @superluminary 如果您为开发设置本地域(例如,通过/etc/hosts),它可以正常工作。
  • 注意:如果您在本地使用 Pow 并拥有 mydomain.com.dev,则 request.domain 返回 .com.dev。将request.domain 更改为request.host 即可完美运行。
  • 我发现我必须为此创建未命名的路由,否则我会收到Invalid route name, already in use: 'root' 错误...为此,我将路由更改为root :to => 'mydomain#index', as: nil
【解决方案2】:

在 Rails 5 中,您可以在路由中简单地执行此操作:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-27
    • 2018-07-20
    • 2011-08-27
    • 2012-02-02
    • 1970-01-01
    • 2021-03-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多