Rails маршрутизация для обработки нескольких доменов в одном приложении - PullRequest
85 голосов
/ 17 ноября 2010

Мне не удалось найти работоспособное решение этой проблемы, несмотря на несколько похожих вопросов здесь и в других местах. Кажется вероятным, что на этот вопрос не ответили для Rails 3, так что вот так:

У меня есть приложение, которое в настоящее время позволяет пользователям создавать свой собственный поддомен, который содержит их экземпляр приложения. В то время как в Rails 2 вам лучше всего использовать гем subdomain-fu, в версии 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/).

Кто-нибудь может порекомендовать способ использования маршрутов для принятия произвольного домена и передачи его контроллеру, чтобы я мог показать соответствующий контент?

Обновление : я получил большую часть ответа сейчас благодаря своевременному ответу Леонида и новому взгляду на код. В конечном итоге это потребовало дополнения к существующему коду субдомена, который я использовал (из решения Railscast), а затем добавило немного в rout.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

Я добавил второй класс в подражание первому, который известен как работающий. Я просто добавляю условие, гарантирующее, что входящий домен не тот, для которого я размещаю основной сайт.

Этот класс используется вways.rb:

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

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

Здесь я добавляю существующий код субдомена (опять же, он работает нормально) со строфой для проверки домена. Если этот сервер отвечает на этот домен, а не тот, под которым работает основной сайт, перешлите к указанному контроллеру.

И хотя это, похоже, работает, у меня еще не все работает, но я думаю, что эта конкретная проблема была решена.

Ответы [ 2 ]

93 голосов
/ 19 января 2011

На самом деле в 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')
2 голосов
/ 08 августа 2018

В Rails 5 вы можете просто сделать это на своих маршрутах:

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