2009-10-05 68 views
5

我正在使用Rails 2.3構建包含各種模塊(博客,日曆等)的CMS。每個模塊由不同的控制器處理,並且工作得很好。基於數據庫的動態導軌路由

我唯一的問題是根URL。根據用戶選擇的配置,這個默認的URL應該顯示一個不同的模塊,即不同的控制器,但唯一的方法是確定正確的控制器是通過檢查數據庫來查看「默認」模塊的顯示內容。

目前,我正在使用特定的「根」控制器來檢查數據庫,並將重定向到到正確的控制器。不過,我寧願URL不要改變,這意味着我想從相同的請求調用正確的控制器。

我試過使用Rails Metal來獲取這些信息並手動調用我想要的控制器,但我想我可能會重新發明輪子(確定請求路徑來選擇控制器,管理會話等)。

有什麼想法?提前感謝!

這段代碼在lib/root_rewriter.rb

module DefV 
    class RootRewriter 
    def initialize(app) 
     @app = app 
    end 

    def call(env) 
     if env['REQUEST_URI'] == '/' # Root is requested! 
     env['REQUEST_URI'] = Page.find_by_root(true).uri # for example /blog/ 
     end 

     @app.call(env) 
    end 
    end 
end 
config/environment.rb

然後在底部

require 'root_rewriter' 
ActionController::Dispatcher.middleware.insert_after ActiveRecord::QueryCache, DefV::RootRewriter 

這個中間件將檢查

回答

5

這個問題可以通過一些Rack中間件來解決請求頁面(REQUEST_URI)爲'/',然後查找實際路徑(執行此操作取決於您;-))。你可能會在緩存這個信息的地方做得很好(Cache.fetch('root_path') { Page.find... }

檢查REQUEST_URI有一些問題,因爲並不是所有的網絡服務器都能正確傳遞這個信息。對於Rails的整個實現細節看http://api.rubyonrails.org/classes/ActionController/Request.html#M000720(點擊「查看源文件」)

+0

是的,這個作品!這或多或少是我已經試圖做的,但直到現在還沒有成功。謝謝你! – 2009-10-20 09:14:35

2

在Rails 3.2,這是什麼,我想出了(還是中間件):

class RootRewriter 
    def initialize(app) 
    @app = app 
    end 

    def call(env) 
    if ['', '/'].include? env['PATH_INFO'] 
     default_thing = # Do your model lookup here to determine your default item 
     env['PATH_INFO'] = # Assemble your new 'internal' path here (a string) 
     # I found useful methods to be: ActiveModel::Naming.route_key() and to_param 
    end 

    @app.call(env) 
    end 
end 

這告訴Rails該路徑不同於所請求的(根路徑),所以引用link_to_unless_current等仍然工作良好。

加載了中間件,像這樣在初始化器:

MyApp::Application.config.middleware.use RootRewriter