导轨/Friendly_id。如何为旧的(丑陋的)URL 呈现 404 页面

Posted

技术标签:

【中文标题】导轨/Friendly_id。如何为旧的(丑陋的)URL 呈现 404 页面【英文标题】:Rails / Friendly_id. How to render 404 pages for old (ugly) URLs 【发布时间】:2016-04-13 04:22:06 【问题描述】:

我已经为一个新的 Rails 应用程序安装了 friendly_id gem,以便为用户配置文件创建漂亮的 URL。一切正常,但我希望旧的(丑陋的)URL 返回 404 页面,因为它应该是正常的。此时,可以通过这两个 URL 获得用户配置文件:

丑陋(旧)网址:/profile/11 漂亮的网址:/profile/jon-smith

我正在使用的路由规则:

get 'profile/:id', to: 'users#show', as: 'user'

用户控制器:

class UsersController < ApplicationController
    def show
        @user = User.friendly.find(params[:id])
    end
end

奇怪的是,我在网上找不到任何可以帮助我解决这个问题的东西,所以有什么想法吗?

【问题讨论】:

【参考方案1】:

我实际上发现这个东西正在工作,它没有出现在当前的 gem 文档中。

class UsersController < ApplicationController
    def show
        @user = User.find_by_slug!(params[:id])
    end
end

将它留在这里以防其他人需要它

更新

此外,使用history 模块意味着使用@user = User.friendly.find(params[:id]),它首先在slug 列中搜索匹配,然后搜索过去的slug,最后通过id。基本上,使用history 模块将/profile/past-friendly-id/profile/id301 重定向到/profile/current-friendly-id,我希望/profile/id 只返回一个404 代码和页面。

这让我想出了一个更干净的解决方案,将gem的finder方法更改为仅通过friendy-id搜索:

# /config/initializers/choose_name.rb
FriendlyId::FinderMethods.module_eval do
    def find(*args)
        id = args.first
        find_by_friendly_id(id)
    end
end

【讨论】:

【参考方案2】:

很高兴看到你修好了!

我打算提出类似的建议;既然我在这里,我不妨写一下,您也可以使用find_by 方法实现相同的功能:

#app/controllers/users_controller.rb
class UsersController < ApplicationController
   def show
      @user = User.find_by slug: params[:id]
   end
end

--

你也可以让你的路线更清晰一点:

#config/routes.rb
resources :users, path: "profile", only: :show, as: :user

更新

如果您想使用 history 模块,您必须使用以下内容:

#app/models/user.rb
class User < ActiveRecord::Base
   friendly_id :username, use: [:finders, :slugged, :history]
end

...或者,您也可以全局设置history 模块:

#config/initializers/friendly_id.rb
...
config.use :finders
config.use :history
config.use :slugged

这基本上会将您的 slug 复制到另一个表(默认情况下称为 friendly_id_slugs),然后 FriendlyID 将在未来查找:

#config/application.rb
FriendlyId::Slug.table_name = "slugs"

我们使用以下内容将表格更改为 slugs

--

重要的一点是history 模块只适用于以前的 slug。

您最初的问题是关于使用ids,而不是以前的蛞蝓。如果您只想查找以前的 slug,是的,您可以使用 User.friendly.find(params[:id])

【讨论】:

好吧,看来我碰壁了,因为使用friendly_id gem :history(将过去的用户页面重定向到当前页面)选项我需要使用它的友好方法,如@user = User.friendly .find(params[:id]) 添加 friendly_id 的 :history 选项 (rubydoc.info/github/norman/friendly_id/FriendlyId/History),我需要使用它的友好方法,如 @user = User.friendly.find(params[:id]) 重定向 /profile/past-jon或 /profile/jons-id 到 /profile/jon。它可能首先搜索以找到匹配的 slug,然后是历史 slug 或具有相同 id 的匹配记录。所以我认为修改通过 id 搜索的 gem 的 finder 方法将是最干净的路线,但不知道在这里改变什么:github.com/norman/friendly_id/blob/master/lib/friendly_id/… 问题不是关于过去的蛞蝓,而是关于如果用户用他们的id 击中show 操作时显示404。这就是我给出的答案;如果您想要过去的 slug,则需要使用 history 模块,但您必须添加一个额外的表(更新文章) 是的。我想要404,如果用户用他们的id点击了show action。但是添加 history 隐含使用 @user = User.friendly.find(params[:id]) 的模块,除了搜索过去的 slug 还按用户 ID 搜索,因此它不会再返回 404 页面来查找 /profile/1 之类的内容。我最终所做的是修改 gem 的 finder 方法以仅使用友好的 id 进行搜索。我也会用这个更新我的答案。感谢您的帮助,它引导我朝着正确的方向前进! 没问题的人,如果你给了它,谢谢你的支持。除非您正在运行诸如论坛/博客之类的东西,否则历史模块不是必需的,其中引用的 URL 是用户查找书签页面等所必需的。期待看到您的更新:)【参考方案3】:

让我们自己尝试遵循代码 sn-p。

class UsersController < ApplicationController
  def show
    if params[:id].to_s.match(/^[0..9]+$/) && !User.friendly.exists?(params[:id])
      render "public/404.html", status: 404
    else
      @user = User.friendly.find params[:id]
    end
  end
end

希望对你有所帮助。

【讨论】:

是的,但这并没有涵盖所有内容,因为在一个开放的平台上,如果有人选择 34567 作为他们的用户名,就会出现问题。我可以进一步限制用户名,但显然我更喜欢更简洁的解决方案,如果有的话 好的。看。实际上,您希望为 id 参数渲染 404 页面的格式为数字。但是如果你想要用户名可以是数字格式。你可以再看看我上面的答案。

以上是关于导轨/Friendly_id。如何为旧的(丑陋的)URL 呈现 404 页面的主要内容,如果未能解决你的问题,请参考以下文章

如何为嵌套资源丰富的路线制作更短的路径

如何为 >= Vista 自定义 FileOpen 对话框?

如何为配置脚本指定包含目录

如何为不同版本的 Xcode 编写条件

如何为旧版 Android API 实现 TextView 行间距方法?

如何为如下所示的 JavaScript 库编写 Typescript 定义文件?