2010-09-07 2 views
16

Я задавался вопросом, были ли какие-либо плагины или методы, которые позволяют мне преобразовывать маршруты ресурсов, которые позволяют мне помещать имя контроллера в качестве поддомена.Rails Restful Routing and Subdomains

Примеры:

map.resources :users 
map.resource :account 
map.resources :blog 
... 

example.com/users/mark 
example.com/account 
example.com/blog/subject 
example.com/blog/subject/edit 
... 

#becomes 

users.example.com/mark 
account.example.com 
blog.example.com/subject 
blog.example.com/subject/edit 
... 

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

+2

Я добавил 100 рецензий на это - я столкнулся с подобной дилеммой, поэтому жизнеспособный ответ был бы замечательным. – Jeriko

+0

Какая версия Rails? 2.x или 3? – tommasop

+0

В моем случае 2.3, хотя Джерико заслуживает большего внимания на этом сейчас. – mark

ответ

3

Лучший способ сделать это, чтобы написать библиотеку промежуточного слоя простой стойки, которая переписывает заголовки запроса так что ваше приложение rails получает URL-адрес, который вы ожидаете, но с точки зрения пользователя URL-адрес не изменяется. Таким образом, вам не нужно вносить какие-либо изменения в приложение рельсы (или файл маршрутов)

Например стеллаж Lib будет переписывать: users.example.com => example.com/users

Это драгоценный камень должен делать то, что для вас: http://github.com/jtrupiano/rack-rewrite

ОБНОВЛЕНО с КОДА

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

# your rack middleware lib. stick this in you lib dir 
class RewriteSubdomainToPath 

    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    original_host = env['SERVER_NAME'] 
    subdomain = get_subdomain(original_host) 
    if subdomain 
     new_host = get_domain(original_host) 
     env['PATH_INFO'] = [subdomain, env['PATH_INFO']].join('/') 
     env['HTTP_X_FORWARDED_HOST'] = [original_host, new_host].join(', ') 
     logger.info("Reroute: mapped #{original_host} => #{new_host}") if defined?(Rails.logger) 
    end 

    @app.call(env) 

    end 

    def get_subdomain 
    # code to find a subdomain. simple regex is probably find, but you might need to handle 
    # different TLD lengths for example .co.uk 
    # google this, there are lots of examples 

    end 

    def get_domain 
    # get the domain without the subdomain. same comments as above 
    end 
end 

# then in an initializer 
Rails.application.config.middleware.use RewriteSubdomainToPath 
+0

Это имеет для меня наибольшее значение, поскольку акцент делается на том, чтобы успокоиться. Если вы можете разработать немного больше, возможно, с примером кода, я дам вам щедрость. Будет ли у этого метода какие-либо потенциальные проблемы с файлами cookie? – Jeriko

+0

Обновлен с примером кода. Куки-файлы должны быть в порядке, так как все запросы будут поступать в тот же базовый домен, что и ваше приложение-рельс. Если вы не пытаетесь поддерживать разные наборы файлов cookie для каждого пользователя. – Nader

+0

Черт - похоже, щедрость просрочена, прежде чем я смог бы ее наградить. Не уверен, полностью ли он потерян или есть что-нибудь, что я могу сделать, чтобы его восстановить, выяснится. – Jeriko

5

Я думаю, что subdomain-fu плагин - это то, что вам нужно. С его помощью вы сможете прокладывать маршруты, как

map.resources :universities, 
    :controller => 'education_universities', 
    :only => [:index, :show], 
    :collection => { 
     :all => :get, 
     :search => :post 
    }, 
    :conditions => {:subdomain => 'education'} 

Это произведет следующее:

education.<your_site>.<your_domain>/universities GET 
education.<your_site>.<your_domain>/universities/:id GET 
education.<your_site>.<your_domain>/universities/all GET 
education.<your_site>.<your_domain>/universities/search POST 
+0

Привет, Игорь и спасибо за ваш ответ. Я посмотрел на subdomainfu, но проблема в том, что он эффективно добавляет пространство имен в качестве имени поддомена, вместо того, чтобы использовать имя контроллера, на что я надеялся. В вашем примере я хотел бы отказаться от образования и переместить университеты (имя контроллера) в качестве субдомена. – mark

+0

Привет, Марк, теперь у меня такая же проблема, и это то, что я сделал. Я создал пространство имен Education, с параметрами: name_prefix => '' и: path_prefix => ''. В этом пространстве имен вы можете делать все, что хотите, у меня есть несколько дополнительных пространств имён. Но для каждого маршрута внутри него вы должны добавить: conditions => {: subdomain => 'education'}. Я не знаю, как лучше писать об этом, но я думаю, что он работает хорошо. Если хотите, свяжитесь со мной, и я покажу вам. –

0

Ryan Bates охватывает это в его Railscast, Subdomains.

+1

Извините Yasky, Railscast на самом деле не обращается к успокоительным субдоменам, и это заканчивается тем, что немного расплывчато. Не мой -1. – Jeriko

3

Это возможно без использования плагинов.

Учитывая структуру каталогов app/controllers/portal/customers_controller.rb И я хочу, чтобы иметь возможность вызвать URL помощников с префиксом portal, т.е. new_portal_customer_url. И URL будет доступен только через http://portal.domain.com/customers. Тогда ... используйте:

constraints :subdomain => 'portal' do 
    scope :module => 'portal', :as => 'portal', :subdomain => 'portal' do 
    resources :customers 
    end 
end 
2

Как ileitch упоминалось вы можете сделать это без дополнительных драгоценных камней это действительно просто на самом деле.

У меня есть стандартные свежие рельсы приложение со свежим эшафот пользователя и контроллер приборной панели для моего администратора, так что я просто пойти:

constraints :subdomain => 'admin' do 
    scope :subdomain => 'admin' do 
     resources :users 

     root :to => "dashboard#index" 
    end 
end 

Так что это идет от этого:

  • site.com/пользователей

к этому:

  • admin.site.com/users

вы можете включить другой корень: to => "{controller} # {action}" за пределами этого ограничения и области для сайта site.com, который можно было бы назвать контроллером страниц. Это было бы получить вам:

constraints :subdomain => 'admin' do 
    scope :subdomain => 'admin' do 
     resources :users 

     root :to => "dashboard#index" 
    end 
end 

root :to => "pages#index" 

Это будет решить:

  • site.com
  • admin.site.com
  • admin.site.com/users