在 Rails 的根路径中使用 FriendlyId 时如何使用命名路由

问题描述

我在 Page 中有一个基本的 Rails 模型,我将它与 FriendlyId 一起使用,以允许管理员创建 "/about""/contact" 之类的页面

我的路由文件 (config/routes.rb) 中有以下内容,以确保每个页面的 slug 出现在站点的根目录中,例如 https://example.com/about 等:

resources :pages,except: [:show]
resources :pages,only: [:show],path: "/"

问题是,使用这种方法,我不能在我的视图(或测试或控制器)中使用像 page_path(@page) 这样的普通命名路由,因为它路由到 "/pages/about" 并且我得到"No route matches [GET] pages/about" error.

我可以在我的路由文件中执行这两个路由,以便 "/pages/about""/about" 像这样工作:

resources :pages
resources :pages,path: "/"

但是,这会产生 SEO 重复的内容问题。我想我可以创建一个帮助程序,为 rel="canonical" 标题中的每个页面设置 html url,但这也感觉像是一个黑客。我希望根目录下的每个页面只有 1 个版本,并且还有一个命名路由,例如 "page_path""root_page_path",我可以在整个应用程序中使用。

我暂时想到的 hack 是 <%= link_to "#{page.slug}" %>,但没有命名路由似乎很脆弱。

Rails 中执行此操作的更“正确”方法是什么?

我希望这样的事情能奏效:

resources :pages,path: "/",as: "page"

但这也行不通。 Rails guide on routing 中的任何内容也没有真正的帮助。

解决方法

你需要 top 切换它们的定义顺序:

resources :pages,only: [:show],path: "/"
resources :pages,except: [:show]

resources 只为具有给定 url 的第一个路径命名。但是 - 您现在会遇到问题,因为 pages/:id 路径(用于删除和更新)现在没有路由助手(因为它通常与 show 相同)。

编辑:如评论中所述 - 它还会自动将 /pages 路径与 id 等于 pages 的显示操作匹配 - 不是一个好主意!这会导致更好的选择:

resources :pages,except: [:show]
get :id,to: "pages#show",as: :root_page

这为您提供了 root_page_path(@page) 操作的 :show 助手和 page_path(@page):update:delete