web-dev-qa-db-fra.com

Routage Rails pour gérer plusieurs domaines sur une seule application

J'ai été incapable de trouver une solution viable à ce problème, malgré plusieurs questions similaires ici et ailleurs. Il semble probable que cette question n'ait pas reçu de réponse pour Rails 3, alors voici:

J'ai une application qui permet aux utilisateurs de créer leur propre sous-domaine contenant leur instance de l'application. Tandis que dans Rails 2, vous étiez mieux servi en utilisant la gemme subdomain-fu, dans la version 3, il est considérablement plus simple, selon Railscast - http://railscasts.com/episodes/221-subdomains-in-Rails-3 .

C'est bien, mais je souhaite également offrir aux utilisateurs la possibilité d'associer leur propre nom de domaine à leur compte. Ainsi, bien qu’ils puissent avoir http://userx.mydomain.com , je voudrais qu’ils choisissent d’associer _ { http://userx.com }.

J'ai trouvé quelques références à cela dans Rails 2, mais ces techniques ne semblent plus fonctionner (en particulier celle-ci: http://feefighters.com/devblog/2009/01/21/hosting-multiple- domaines-d'un-single-Rails-app / ). 

Quelqu'un peut-il recommander un moyen d'utiliser des itinéraires pour accepter un domaine arbitraire et le transmettre à un contrôleur afin que je puisse afficher le contenu approprié?

Mise à jour: J'ai obtenu l'essentiel de la réponse maintenant, grâce à la réponse opportune de Leonid et à un nouveau regard sur le code. Cela a finalement nécessité un ajout au code de sous-domaine existant que j’utilisais (de la solution Railscast), puis un peu à routes.rb. Je ne suis pas encore au bout de mon chemin mais je veux poster ce que j'ai jusqu'à présent.

Dans 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

J'ai ajouté la deuxième classe à l'imitation de la première, qui est connue pour fonctionner. J'ajoute simplement une condition garantissant que le domaine entrant n'est pas celui pour lequel j'héberge le site principal.

Cette classe est utilisée dans routes.rb:

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

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

Ici, je préfixe le code de sous-domaine existant (encore une fois, il fonctionne bien) avec une strophe pour rechercher le domaine. Si ce serveur répond à ce domaine et que ce n'est pas celui sous lequel le site principal fonctionne, transmettez-le au contrôleur spécifié.

Et bien que cela semble fonctionner, je n'ai pas encore tout à fait travaillé, mais je pense que ce problème particulier a été résolu.

83
Aaron Vegh

C'est en fait plus simple dans Rails 3, comme indiqué dans http://guides.rubyonrails.org/routing.html#advanced-constraints :

1) définissez une classe de contrainte personnalisée dans lib/domain_constraint.rb:

class DomainConstraint
  def initialize(domain)
    @domains = [domain].flatten
  end

  def matches?(request)
    @domains.include? request.domain
  end
end

2) utiliser la classe dans vos itinéraires avec la nouvelle syntaxe de bloc

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

root :to => 'main#index'

ou la syntaxe des options à l'ancienne

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

Dans Rails 5, vous pouvez simplement le faire dans vos itinéraires:

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