ruby-on-rails - 带有智能重定向的 StackOverflow 风格路由

标签 ruby-on-rails routes friendly-id

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。

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

我认为在 routes.rb 文件中不可能出现这种情况的原因是,通常您无权访问该对象(因此您无法根据ID,对吗?)

对于任何感兴趣的人,Rails 3.2.13 以及还使用 FriendlyID

最佳答案

好的,我想我已经明白了。

我正在考虑使用中间件做一些事情,但后来决定这可能不适合这种类型的功能(因为我们需要访问 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

这很容易实现到我的 Controller 中:

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

该服务是以通用方式编写的,因此我可以在任何资源丰富的 Controller 中使用它。我还没有找到打破它的方法,但我愿意接受纠正。

资源

Railscast #398: Service Objects by Ryan Bates

This Helpful Tweet by Jared Fine

关于ruby-on-rails - 带有智能重定向的 StackOverflow 风格路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16654671/

相关文章:

ruby-on-rails - 下拉列表选项值为空

ruby-on-rails - 生成 422 错误的错误页面

Symfony 3 - 具有多个可选参数的路由

routes - 帖子上的 mvc 自定义路由空模型

ruby-on-rails - FriendlyID unique slugs by scope 和 active admin

ruby-on-rails - friendly_id,从历史记录中删除 slug

ruby-on-rails - 如何在 Rails 中编辑 twitter Bootstrap 文件?

ruby-on-rails - Rails 3 开发环境保持缓存,即使没有缓存?

ruby-on-rails - Rails 3 ActiveRecord 预先加载范围

android - 如何以友好的名称获取绑定(bind)的蓝牙设备列表