2010-09-07 76 views
16

我想知道是否有任何插件或方法允許我轉換資源路由,使我可以將控制器名稱作爲子域名。Rails Restful路由和子域名

例子:

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 2010-09-20 12:00:46

+0

哪個版本的Rails? 2.x或3? – tommasop 2010-09-24 09:51:54

+0

在我的情況下,2.3,儘管jeriko現在值得更多的關注。 – mark 2010-09-24 10:49:55

回答

3

做到這一點是寫一個重寫請求頭一個簡單的機架中間件庫的最佳方式以便您的Rails應用獲取您期望的url,但從用戶的角度來看,url不會更改。這樣,您就不必對您的Rails應用程序的任何更改(或路由文件)

例如機架的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 2010-09-27 09:58:48

+0

更新了代碼示例。就您的Rails應用程序而言,Cookie應該沒問題,因爲所有請求都會到達相同的基本域。除非您試圖爲每個用戶維護不同的Cookie。 – Nader 2010-09-27 22:04:34

+0

該死 - 看來在我可以獎勵給你之前,賞金已經過期了。不知道它是否完全丟失,或者如果有什麼我可以做的恢復它,會發現.. – Jeriko 2010-09-28 10:10:20

5

我認爲subdomain-fu插件是exacly你所需要的。 有了它,你將能夠產生像

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 2010-09-07 12:19:13

+0

Hello Mark,現在我有同樣的問題,那就是我所做的。我創建了命名空間教育,參數爲:name_prefix =>''和:path_prefix =>''。在這個命名空間中,你可以做任何你想做的事,我在裏面有幾個額外的命名空間。但是對於其中的每條路線,您應該添加:conditions => {:subdomain =>'education'}。我不知道,如何寫得更好,但我認爲它運作良好。如果你願意,請聯繫我,我會告訴你。 – 2010-09-09 07:24:05

0

瑞恩·貝茨包括這在他的Railscast,Subdomains

+1

對不起Yasky,Railscast並沒有真正解決寧靜的子域問題,而且它最終有點含糊。雖然不是我的-1。 – Jeriko 2010-09-27 09:55:44

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提到的,你可以做到這一點沒有額外的寶石是非常簡單的實際。

我有一個新的用戶腳手架和我的管理儀表板控制器標準的新的Rails應用程序,所以我只是去:

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}」,該約束和作用域可以被稱爲頁面控制器。這將讓你這樣的:

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