导轨/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 获得用户配置文件:
我正在使用的路由规则:
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/id
与301
重定向到/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 对话框?