2013-08-28 72 views
1

我正在開發使用煉油廠的網站。現在,在煉油廠的後端創建一個特定的頁面,我想使用我自己的控制器和視圖。所有用戶可以使用此頁面來設置菜單位置,標題,元信息等。此頁面的URL必須與所有其他頁面相同。Rails運行時動態路由

因此,例如,菜單結構如下:

  • menux
  • MENU1
    • MENU2
      • 特定頁面
  • menux

而對於「特定的頁面」的URL看起來像「區域設置/菜單1/MENU2 /特定頁面」

該網站提供多種語言,所以我必須創建這些路由所有的語言。

目前我創建的路線是這樣的:

specific_page_id = 1 
Refinery::I18n.frontend_locales.each do |lang| 
    slugs = [] 
    page = Refinery::Page.find_by_path_or_id(nil, specific_page_id) 
    # get slug for page in current language 
    slugs << page.translations.select { |p| p.locale == lang }.first.slug 

    # get all slugs from parrent pages 
    while !page.parent_id.blank? 
    page = Refinery::Page.find_by_path_or_id(nil, page.parent_id) 
    slugs << page.translations.select { |p| p.locale == lang }.first.slug 
    end 

    match "/:locale/#{slugs.reverse.join("/")}" => "controller#action", :via => :get, :constraints => { :locale => /#{lang}/ } 
end 

有了這個,我越來越到指定頁面的路徑在每一個語言如上述。

但問題是,當用戶更改頁面的名稱或菜單中的位置時,必須重新生成路由,但這並不經常進行。

現在我的問題是,如何在運行時更動態地執行此操作?我已閱讀了一些關於約束的內容,但我不知道這是否是我需要的。

感謝您的幫助!

+0

一點兒也不缺省路由,這樣|獲取'照片/:id',到:'photos#show'|爲你工作? – techvineet

+0

沒有,因爲用戶可以改變照片製作成圖片,然後路線將不得不像:讓「圖片/:身份證」,到:「照片#秀」 –

+0

如果控制器一樣,你會更好地轉移部分到佔位符的路徑並使用約束。可能是'':name /:id',爲:'photo#show''比較好。 – Bigxiang

回答

5

我需要弄清楚建設路線關(數據庫模型自己在Rails應用4這是在下面的例子中被稱爲「ComingSoon」。我想,可能在後端進行編輯,並給予用戶頁面。友好的名稱,它存儲在頁#名稱字段,以便"About Us"標題頁通常會變得"about_us"名,從而導致"http://localhost:3000/about_us"以下是我想出了技術:

創建應用程序/模型/ dynamic_router新模式.rb

class DynamicRouter 
    def self.load 
    ComingSoon::Application.routes.draw do 
     Page.all.each do |pg| 
     get "/#{pg.name}", :to => "pages#show", defaults: { id: pg.id }, as: "pages_#{pg.name}" 
     end 
    end 
    end 

    def self.reload 
    ComingSoon::Application.routes_reloader.reload! 
    end 
end 

上面的關鍵是我將頁面的ID作爲其中一個參數,因此查找仍然在Page#id字段上,即,恕我直言,比使用友好的插件或查找漫反值要好得多。

將以下行添加到您的配置/路由。RB

ComingSoon::Application.routes.draw do 

    # ... 

    DynamicRouter.load 
end 

最後,當網頁被更新,我們需要重新加載路線,所以在頁面模型添加after_safe回調:

class Page < ActiveRecord::Base 
    after_save :reload_routes 

    def reload_routes 
    DynamicRouter.reload 
    end 
end 

我計劃進一步完善這一隻重裝路線如果name屬性被改變,也許只需編輯現有的路由,而不是重新加載一切,如果性能被證明是一個問題(這在目前,它不是)。

+0

對於那些有興趣,我貼到我的博客更IN-一點關於在運行時生成路由的深度:http://bit.ly/1c4Ppqc歡迎在這裏或博客文章本身發表評論! –