【问题标题】:StackOverflow Style Routes with Smart Redirects带有智能重定向的 StackOverflow 样式路由
【发布时间】:2013-05-20 17:12:44
【问题描述】:

StackOverflow 似乎有这种风格的提问方式:

/questions/:id/*slug

在路由和to_param 中都很容易实现。

但是,当只传递一个 ID 时,StackOverflow 似乎也会重定向到该路径。

示例:

stackoverflow.com/questions/6841333 

重定向到:

stackoverflow.com/questions/6841333/why-is-subtracting-these-two-times-in-1927-giving-a-strange-result/

弹头的任何变化都一样

stackoverflow.com/questions/6841333/some-random-stuff

仍将重定向到相同的 URL。

我的问题是:这种类型的重定向通常在控制器中处理(将请求与路由进行比较)还是有办法在 routes.rb 中执行此操作?

我认为在 routes.rb 文件中不可能做到这一点的原因是,您通常无权访问该对象(因此您无法根据 ID 获取 slug,对吧?)

对于任何感兴趣的人,Rails 3.2.13 并使用FriendlyID

【问题讨论】:

  • 也许他们使用正则表达式去除参数的 id 部分以进行更快的查找,然后基于此重定向。我还假设他们将 id 保留在 url 中,这样如果问题具有相同的标题,则 url 是唯一的。这也看起来像控制器逻辑。

标签: ruby-on-rails routes friendly-id


【解决方案1】:

好的,我想我知道了。

我正在考虑用中间件做一些事情,但后来决定这可能不是这种功能的地方(因为我们需要访问 ActiveRecord)。

所以我最终构建了一个服务对象,称为PathCheck。服务如下所示:

class PathCheck
  def initialize(model, request)
    @model = model
    @request = request
  end 

  # Says if we are already where we need to be
  # /:id/*slug
  def at_proper_path?
    @request.fullpath == proper_path
  end

  # Returns what the proper path is
  def proper_path
    Rails.application.routes.url_helpers.send(path_name, @model) 
  end

private
  def path_name
    return "edit_#{model_lowercase_name}_path" if @request.filtered_parameters["action"] == "edit"
    "#{model_lowercase_name}_path"
  end

  def model_lowercase_name
    @model.class.name.underscore
  end
end

这很容易在我的控制器中实现:

def show
  @post = Post.find params[:post_id] || params[:id]
  check_path
end

private
  def check_path
    path_check = PathCheck.new @post, request
    redirect_to path_check.proper_path if !path_check.at_proper_path?
  end

我在find 方法中的|| 是因为为了维护资源丰富的路线,我做了类似...

resources :posts do
  get '*id' => 'posts#show'
end

这将在/posts/:id 之上创建类似:/posts/:post_id/*id 的路线

这样,数字 id 主要用于查找记录(如果可用)。这允许我们松散匹配 /posts/12345/not-the-right-slug 以重定向到 /posts/12345/the-right-slug

该服务以通用方式编写,因此我可以在任何资源丰富的控制器中使用它。我还没有找到破解它的方法,但我愿意更正。

资源

Railscast #398: Service Objects 瑞恩·贝茨

This Helpful Tweet Jared Fine

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-03
    • 1970-01-01
    • 2020-02-13
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    相关资源
    最近更新 更多