Enrutamiento de raíles para manejar múltiples dominios en una sola aplicación

No he podido encontrar una solución viable para este problema, a pesar de varias preguntas similares aquí y en otros lugares. Parece probable que esta pregunta no haya sido respondida para Rails 3, así que aquí va:

Tengo una aplicación que actualmente permite a los usuarios crear su propio subdominio que contiene su instancia de la aplicación. Mientras que en Rails 2 era mejor utilizar la gem subdomain-fu, en la versión 3 es mucho más simple, según Railscast – http://railscasts.com/episodes/221-subdomains-in-rails-3 .

Eso es bueno, pero también quiero ofrecer la opción para que los usuarios asocien su propio nombre de dominio con su cuenta. Entonces, si bien podrían tener http://userx.mydomain.com , me gustaría que también eligieran tener asociado http://userx.com .

Encontré algunas referencias para hacer esto en Rails 2, pero esas técnicas ya no parecen funcionar (particularmente esta: http://feefighters.com/devblog/2009/01/21/hosting-multiple-domains-from -a-single-rails-app / ).

¿Alguien puede recomendar una forma de usar rutas para aceptar un dominio arbitrario y pasarlo a un controlador para que pueda mostrar el contenido apropiado?

Actualización : ahora recibí la mayor parte de la respuesta, gracias a la respuesta oportuna de Leonid y una nueva mirada al código. Finalmente requirió una adición al código de Subdominio existente que estaba usando (de la solución de Railscast) y luego agregó un bit a routes.rb. Todavía no llegué allí, pero quiero publicar lo que tengo hasta ahora.

En 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 

He agregado la segunda clase en imitación de la primera, que se sabe que funciona. Simplemente agrego una condición que asegura que el dominio entrante no sea el que estoy hospedando en el sitio principal.

Esta clase se usa en routes.rb:

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

Aquí, prefiero el código de subdominio existente (de nuevo, funciona bien) con una estrofa para verificar el Dominio. Si este servidor responde a ese dominio y no es bajo el cual opera el sitio principal, reenvíelo al controlador especificado.

Y aunque parece funcionar, todavía no tengo todo funcionando, pero creo que este problema en particular se ha resuelto.

En realidad es más simple en Rails 3, según http://guides.rubyonrails.org/routing.html#advanced-constraints :

1) define una clase de restricción personalizada en lib/domain_constraint.rb :

 class DomainConstraint def initialize(domain) @domains = [domain].flatten end def matches?(request) @domains.include? request.domain end end 

2) usa la clase en tus rutas con la nueva syntax de bloque

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

o la syntax de opciones antigua

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

En Rails 5, simplemente puede hacer esto en sus rutas:

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