具有约束的通配符路由以尾部斜杠结束

时间:2014-07-02 18:00:34

标签: ruby-on-rails

我有2个通配符路径,如下所示:

get '*country_path/', to: 'country#list', constraints: { country_path: /\/$/ }
get '*country_path/:title', to: 'country#show'
当url有一个尾部斜杠时,应该调用

country#list。例子:

www.example.com/usa/california/
www.example.com/usa/california/abc/

country#show应该在没有尾部斜杠时调用。例子:

www.example.com/usa/californa/travel
www.example.com/usa/californa/average-income

目前我的约束似乎不起作用,因为所有请求都转到country#list。

我的路线限制有什么问题?

2 个答案:

答案 0 :(得分:7)

你应该问问自己这是否真的是完成你想要做的事情的最好方法。网站通常不关心目录中的尾部斜杠。例如:

www.facebook.com/username

将带你到同一个地方:

www.facebook.com/username/

绝大多数网站都是这样工作的,所以你现在要做的就是反对网络惯例。如果你关心它,肯定会对SEO产生影响。即使你不这样做,也应该考虑在测试这些路线时你将面临的困难。你的测试会很脆弱,从长远来看这会引起很多挫折。

我的建议如下:如果您想区分listshow,请将这些内容放入网址中。例如:

www.example.com/usa/california/list
www.example.com/usa/california/abc/list

可以将用户带到country#list,将“california”和“abc”作为参数。类似地:

www.example.com/usa/californa/travel/show
www.example.com/usa/californa/average-income/show

可以将用户带到country#show。这要容易得多。它也更标准和用户友好。有关详细信息,请参阅Rails Routing from the Outside In.

答案 1 :(得分:2)

问题是Rails在到达路由之前已经删除了尾随/,因此使用传统方法无法匹配它。唯一的方法是使用advanced constraint。以下内容适合您的需求:

# config/routes.rb
class TrailingSlashMatcher
  def matches?(request)
    uri = request.env["REQUEST_URI"]
    uri.present? && uri.end_with?("/")
  end
end

Rails.application.routes.draw do
  get '*country_path', to: 'country#list', :constraints => TrailingSlashMatcher.new
  get '*country_path/:title', to: 'country#show'
end

(取自here)。

这种方法的问题在于它在所有情况下都不会起作用。它适用于对服务器的实际请求,但在从测试等调用时可能会出现问题。原因是REQUEST_URI env变量不是rack spec的一部分,因此不受测试框架的限制。 env["PATH_INFO"]是强制性的,但会删除尾随/,所以这里不好。

总而言之,重新考虑路线的设计可能是值得的。匹配是否存在尾随/是相当脆弱的。它还可能导致您的用户感到困惑(例如,链接被复制/粘贴等)。没有其他方法可以区分列表和显示请求(可能基于路径的深度)。