Rails 将通配符路由限制为特定格式
Rails restrict wildcard route to certain format
我的 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 不知道如何为 non-html 格式呈现我的错误页面。
我的问题是:如何防止 non-HTML 格式进入我的通配符处理程序?
我尝试了以下方法但无济于事:
格式限制
在路由周围放置一个范围以将其限制为 HTML 格式:
scope :format => true, :constraints => { :format => 'html' } do
get "*client" => "client#show"
end
这确实可以防止资产被路由到我的处理程序,但不幸的是,如果页面明确以 .html
扩展名结尾,则只会将页面路由到处理程序。失败。
格式默认值
接下来,我想尝试使用 default 格式。像这样:
get "*client" => "client#show", :defaults => { :format => 'html' }
不幸的是,仍然没有工作人员。没有变化。我的理解是,如果 Rails 无法从 content-type header 或文件扩展名中找出它,这只是设置默认格式。
我开始认为可能没有办法在路由级别执行此操作。
因为我不知道如何在 route
级别限制资产进入我的处理程序,所以我只是在我的处理程序的开头进行了检查,以便在请求时使处理程序短路不是 HTML 格式。
def show
render nothing: true, status: :not_found and return if invalid_format?
...
end
private
def invalid_format?
request.format != "html"
end
您也许可以做这样的事情并将其放在 get "*client" => "client#show"
路线之前:
scope :format => true, :constraints => { :format => 'example' } do
get "*client" => "error#404"
end
设置您想要捕获的格式,这些格式稍后将与一般格式相匹配 get '*client'
并在它们到达那里之前处理如何处理它们。
我的 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 不知道如何为 non-html 格式呈现我的错误页面。
我的问题是:如何防止 non-HTML 格式进入我的通配符处理程序?
我尝试了以下方法但无济于事:
格式限制
在路由周围放置一个范围以将其限制为 HTML 格式:
scope :format => true, :constraints => { :format => 'html' } do
get "*client" => "client#show"
end
这确实可以防止资产被路由到我的处理程序,但不幸的是,如果页面明确以 .html
扩展名结尾,则只会将页面路由到处理程序。失败。
格式默认值
接下来,我想尝试使用 default 格式。像这样:
get "*client" => "client#show", :defaults => { :format => 'html' }
不幸的是,仍然没有工作人员。没有变化。我的理解是,如果 Rails 无法从 content-type header 或文件扩展名中找出它,这只是设置默认格式。
我开始认为可能没有办法在路由级别执行此操作。
因为我不知道如何在 route
级别限制资产进入我的处理程序,所以我只是在我的处理程序的开头进行了检查,以便在请求时使处理程序短路不是 HTML 格式。
def show
render nothing: true, status: :not_found and return if invalid_format?
...
end
private
def invalid_format?
request.format != "html"
end
您也许可以做这样的事情并将其放在 get "*client" => "client#show"
路线之前:
scope :format => true, :constraints => { :format => 'example' } do
get "*client" => "error#404"
end
设置您想要捕获的格式,这些格式稍后将与一般格式相匹配 get '*client'
并在它们到达那里之前处理如何处理它们。