13

我有一个问题,最近控制器的名称发生了变化。

我更改了路由文件以接受使用旧控制器名称的呼叫,以供书签引用旧名称的人使用:

get '/old/about', to: redirect('/new/about')
get '/old/report/:client', to: redirect('/new/report/%{client}')
get '/old/:sub_path', to: redirect('/new/%{sub_path}')

效果很好。但是对于带有查询字符串的调用,它会将其阻止到 /report/200。例如:

/old/report/200?c_id=257&end=2013-10-19&num_results=294540&start=2013-10-13

它将网址削减为:

旧/报告/200

并由于缺少参数而向我显示错误。你知道我能做什么吗?(我认为路线中的 :sub_path 行会有所帮助,但不会):(

4

4 回答 4

21

修改redirect以使用path:保留查询字符串的选项:

- get '/old/about', to: redirect('/new/about')
+ get '/old/about', to: redirect(path: '/new/about')

这在 API 文档中进行了演示redirect,请参阅http://api.rubyonrails.org/classes/ActionDispatch/Routing/Redirection.html#method-i-redirect

于 2017-02-07T10:29:40.293 回答
12

马特提到的问题帮助我弄清楚了我的答案(非常感谢!)。对于我的具体情况,情况略有不同。我留下对我有用的答案以供将来参考。

match "/old/report/:client" => redirect{ |params, request| "/new/report/#{params[:client]}?#{request.query_string}" }
于 2013-10-23T19:15:16.950 回答
3

基于 Alejandra 的答案,更详细但没有?if there's no 查询字符串:

get "/old/report/:client", to: redirect{ |params, request| ["/new/report/#{params[:client]}", request.query_string.presence].compact.join('?') }

所以/old/report/:client?with=param会变成/new/report/:client?with=param/old/report/:client也会变成/new/report/:client

于 2016-08-04T15:40:54.470 回答
0

现有的答案完美地工作,但不太适合保持干燥——一旦你需要重定向多个路由,就会有很多重复的代码。

在这种情况下,自定义重定向器是一种优雅的方法:

class QueryRedirector
  def call(params, request)
    uri = URI.parse(request.original_url)
    if uri.query
      "#{@destination}?#{uri.query}"
    else
      @destination
    end
  end

  def initialize(destination)
    @destination = destination
  end
end

现在您可以为该redirect方法提供此类的新实例:

get "/old/report/:client", to: redirect(QueryRedirector.new("/new/report/#{params[:client]}"))

我写了一篇文章,有更详细的解释。

于 2019-03-01T10:00:13.950 回答