2015-01-31 47 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