我的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无法从内容类型标题或文件扩展名中找出它。
我开始认为在路线层面可能没有办法做到这一点。
答案 0 :(得分: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
答案 1 :(得分:0)
您可能可以执行此类操作并将其放在get "*client" => "client#show"
路线之前:
scope :format => true, :constraints => { :format => 'example' } do
get "*client" => "error#404"
end
设置要捕获的格式,以便稍后与常规get '*client'
匹配,并在它们到达之前处理如何处理它们。