2015-01-31 19 views
0

我在routes.rb文件通配符路線:Rails的限制通配符路線一定的格式

get "*client" => "client#show" 

在控制器中,我期待了客戶數據庫並顯示其自定義頁面:

def show 
    @client = Client.find_by(slug: params[:client]) 

    if @client.nil? 
    render file: "client/404", layout: "error", status: :not_found 
    return 
    end 
end 

這很好,但我的問題是,找不到的任何資產也通過我的client#show處理程序路由。

這導致客戶端在數據庫中毫無意義的查找,然後我得到500錯誤,因爲Rails不知道如何呈現非HTML格式的錯誤頁面。

我的問題是:如何防止非HTML格式進入我的通配符處理程序?

我已經嘗試了以下無濟於事:

格式約束

把一個範圍的路由解決它限制爲HTML格式:

scope :format => true, :constraints => { :format => 'html' } do 
    get "*client" => "client#show" 
end 

這確實保持資產不被路由到我的處理程序,但不幸的是,如果它們明確以.html擴展名結尾,那麼只會將頁面路由到處理程序。失敗。

格式默認

接下來,我想我會嘗試的格式默認。像這樣:

get "*client" => "client#show", :defaults => { :format => 'html' } 

不幸的是,仍然沒有workee。沒有變化。我的理解是,這只是設置默認格式,如果Rails不能從內容類型頭文件或文件擴展名中弄清楚。

我開始認爲在路線級別可能沒有辦法做到這一點。

回答

0

由於我無法弄清楚如何限制資產進入route級別的處理程序,我只是在處理程序的開始處檢查處理程序,以便在請求不是HTML格式時使處理程序短路。

def show 
    render nothing: true, status: :not_found and return if invalid_format? 
    ... 
end 

private 

def invalid_format? 
    request.format != "html" 
end 
+0

Ruby <2.2?不要將未知輸入轉換爲符號,否則您的應用程序將暴露於DoS內存不足的攻擊(在這種情況下請求多種格式);而是使用'request.format!='html'' – mdesantis 2015-01-31 21:32:07

+0

很高興知道。謝謝@mdesantis。更新了我的答案。 – 2015-02-01 19:40:04

0

您也許能夠做這樣的事和get "*client" => "client#show"路線之前所說的那樣:

scope :format => true, :constraints => { :format => 'example' } do 
    get "*client" => "error#404" 
end 

設置你想趕上,後來匹配一般get '*client'和處理什麼格式在他們到達之前與他們一起做。

+0

感謝您的回答。不過,我寧願不必爲可能的格式製作路線。 – 2015-02-01 19:42:25