단일 애플리케이션에서 여러 도메인을 처리하기위한 Rails 라우팅


90

여기와 다른 곳에서 몇 가지 유사한 질문에도 불구하고이 문제에 대한 실행 가능한 해결책을 찾을 수 없었습니다. 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

나는 일하는 것으로 알려진 첫 번째 클래스를 모방하여 두 번째 클래스를 추가했습니다. 들어오는 도메인이 기본 사이트를 호스팅하는 도메인이 아닌지 확인하는 조건을 추가하기 만하면됩니다.

이 클래스는 route.rb에서 사용됩니다.

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

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

여기서는 도메인을 확인하기 위해 스탠자를 사용하여 기존 하위 도메인 코드 (다시 정상적으로 작동 함)를 추가하고 있습니다. 이 서버가 해당 도메인에 응답하고 기본 사이트가 작동하는 도메인이 아닌 경우 지정된 컨트롤러로 전달합니다.

작동하는 것처럼 보이지만 아직 모든 것이 작동하지는 않지만이 특정 문제가 해결 된 것 같습니다.


1
편집 해주셔서 감사합니다, Aaron. 나는 지금 똑같은 상황을 다루고 있습니다. 후속 질문으로 서버가 전달되는 도메인을 수락하도록하려면 어떻게해야합니까? .conf 파일의 설정이라고 가정하지만 무엇인지 잘 모르겠습니다. 어떤 도움을 주시면 감사하겠습니다!
deadwards 2011

Aaron, 나는 당신과 함께 있습니다. 저도 똑같은 일을하고 싶습니다. 하지만 도메인을 하드 코딩하고 싶지 않습니다. 영역 파일과 웹 서버를 다시 시작하지 않고 프로그래밍 방식으로 모두 완료하고 싶습니다.
Michael K Madison

1
마이클, 문제를 뒤집어 야합니다. 호스트 또는 하위 도메인 제약 조건을 사용하여 애플리케이션 (예 : 가입) 전용 경로를 명시 적으로 선언하고 하드 코딩 한 다음 기본 경로를 "모든 도메인 또는 하위 도메인"으로 취급합니다. 그런 다음 현재 도메인 또는 하위 도메인을 조회하고 올바른 고객에게 매핑하는 것은 컨트롤러의 책임입니다.
Justin French

답변:


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
이 대답 은 나에게 훨씬 더 간단 해 보입니다.
Jared

7
이것은 훌륭한 솔루션입니다. 개발 환경에서 어떻게 작동합니까?
superluminary

2
@superluminary 개발을 위해 로컬 도메인을 설정하면 완벽하게 작동합니다 (예 : via /etc/hosts).
Leonid Shevtsov 2012 년

7
참고 : 로컬에서 Pow를 사용하고 mydomain.com.dev request.domain가있는 경우 .com.dev 를 반환합니다. 로 변경 request.domain하면 request.host완벽하게 작동합니다.
Eric Muyser 2013 년

2
이 작업 Invalid route name, already in use: 'root'을 수행하려면 이름이 지정되지 않은 경로를 만들어야합니다. 그렇지 않으면 오류가 발생합니다. 이렇게하려면 경로를 다음으로 변경했습니다.root :to => 'mydomain#index', as: nil
Just Lucky Really

5

Rails 5에서는 경로에서 간단히 다음과 같이 할 수 있습니다.

constraints subdomain: 'blogs' do
  match '/' => 'blogs#show'
end
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.