URL 比较项目的结构

URL Structure for Comparing Items

构建用于比较多个项目的路由的最佳方式是什么?

这是 URL 示例:https://versus.com/en/microsoft-teams-vs-slack-vs-somalia

如何在 routes.rb 文件中实现这个?在 Internet 上找不到任何关于 ruby gems 的信息。我唯一能想到的是 url 带有可选参数,但是如果参数数量不受限制怎么办?

您将不得不自己解析 a-vs-b-vs-c

所以在 routes.rb 中,你会得到类似的东西:

get 'compare/:compare_string', to 'compare#show'

然后你会得到一个你必须解析的参数compare_string:

#in compare_controller.rb

def show
  compare_items = params[:compare_string].split('-vs-')

  # generate the comparison from the compare_items array
end

首先 - 在实践中您可能不应该允许无限数量的参数。即使像 100 这样的值也可能会破坏您的页面 and/or 导致性能问题并使您容易受到 DOS 攻击。我会选择某种 sensible/practical 限制和 document/enforce 它(例如 10、12 或任何对您的应用程序有意义的值)。在大约 2k 个字符处,您将从 运行 开始变成 URL-length issues.

接下来 - URL 是否有任何灵活性?名称往往会更改,因此如果您希望 URL 随着时间的推移工作,您需要对它们中的每一个进行 slug-ify(使用 friendly-id 之类的东西)以便您可以跟踪随时间的变化。例如 - 您可以使用 immutable/unique ID 和人类可读的名称吗?

无论如何,Rails 为URL 路由提供了一个非常灵活的系统。您可以通过 Rails routing documentation.

阅读有关各种选项/配置的更多信息

默认情况下,Dynamic Segment 支持您示例中的文本,因此(取决于您的控制器名称)您可以执行以下操作:

get 'en/:items', to: 'items#compare'

如果有帮助,您可以添加自定义 constraint 正则表达式以保证参数符合您的预期(例如 word-with-dashes-vs-another-vs-something-else

get 'en/:items', to: 'items#compare', constraints: { items: /(?:(?:[A-Z-]+)vs)+(?:[A-Z-]+)/ }

然后,在您的控制器中,您可以根据需要解析出单独的字符串。像...

  def compare
    items = params[:items].split('-vs-')
  end