0

我的routes.rb文件中有一个通配符路由:

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扩展名结尾,则只会将页面路由到处理程序。失败。

格式默认

接下来,我想我会尝试格式default。像这样:

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

不幸的是,仍然没有工作人员。没有变化。我的理解是,如果 Rails 无法从内容类型标头或文件扩展名中找出它,这只是设置默认格式。

我开始认为在路由级别可能没有办法做到这一点。

4

2 回答 2

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
于 2015-01-31T19:51:13.117 回答
0

您也许可以做这样的事情并将其放在get "*client" => "client#show"路线之前:

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

设置您想要捕获的格式,这些格式稍后将与一般匹配,get '*client'并在它们到达那里之前处理如何处理它们。

于 2015-01-31T21:00:07.460 回答