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

Aar*_*egh 86 subdomain routing routes ruby-on-rails ruby-on-rails-3

尽管在这里和其他地方有几个类似的问题,但我一直无法找到解决这个问题的可行办法.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中找到了一些参考,但这些技术似乎不再起作用了(特别是这一个:http://feefighters.com/devblog/2009/01/21/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
Run Code Online (Sandbox Code Playgroud)

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

此类用于routes.rb:

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

constraints(Subdomain) do
  match '/' => 'blogs#show'
end
Run Code Online (Sandbox Code Playgroud)

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

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

Leo*_*sov 94

根据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
Run Code Online (Sandbox Code Playgroud)

2)使用新的块语法在路由中使用类

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

root :to => 'main#index'
Run Code Online (Sandbox Code Playgroud)

或者老式的选项语法

root :to => 'mydomain#index', :constraints => DomainConstraint.new('mydomain.com')
Run Code Online (Sandbox Code Playgroud)

  • 这是一个很好的解决方案.它如何与开发环境一起使用? (7认同)
  • 注意:如果你在本地使用Pow并拥有mydomain.com.dev,那么`request.domain`将返回.com.dev.将`request.domain`更改为`request.host`,它完美无缺. (7认同)
  • [这个答案](http://stackoverflow.com/a/6058737/396138)对我来说似乎更简单. (6认同)
  • @superluminary如果你为开发设置本地域(例如,通过`/ etc/hosts`),它可以很好地工作. (2认同)
  • 我发现我必须为此创建未命名的路由,否则我得到`无效的路由名称,已经在使用中:'root'.错误...为此,我将路由更改为`root:to >'mydomain #index',as:nil` (2认同)

use*_*467 8

在 Rails 5 中,你可以简单地在你的路线中做到这一点:

constraints subdomain: 'blogs' do
  match '/' => 'blogs#show'
end
Run Code Online (Sandbox Code Playgroud)

  • 如果它不是子域而只是域? (2认同)