【问题标题】:Rails restrict wildcard route to certain formatRails 将通配符路由限制为某种格式
【发布时间】:2015-01-31 19:51:13
【问题描述】:

我的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 扩展名结尾时才会将它们路由到处理程序。失败。

默认格式

接下来,我想尝试一种格式默认。像这样:

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

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

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

【问题讨论】:

    标签: ruby-on-rails actiondispatch


    【解决方案1】:

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

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

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

    【讨论】:

    • 感谢您的回答。不过,我希望不必为所有可能的格式制定路线。
    【解决方案2】:

    由于我无法弄清楚如何在route 级别限制资产进入我的处理程序,我只是在处理程序的开头放置一个检查,以在请求不是 HTML 格式时短路处理程序.

    def show
      render nothing: true, status: :not_found and return if invalid_format?
      ...
    end
    
    private
    
    def invalid_format?
      request.format != "html"
    end
    

    【讨论】:

    • 红宝石 request.format != 'html'
    • 很高兴知道。谢谢@mdesantis。更新了我的答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 1970-01-01
    • 2010-11-25
    • 2013-10-21
    相关资源
    最近更新 更多