我正在为遗留应用程序编写一个替代系统,我们希望旧的URL重定向到新的URL结构。我想在路由中使用重定向帮助器。来完成这个。这对于简单的情况非常有效。但是,有一些遗留标识符包含点。如果标识符包含点,我需要:
- 不丢失标识符的后半部分
- 用破折号替换点
那么,这是我在rspec中的测试:
it "redirects requests correctly when there are dots in the eadid" do
get "/collections/MC001.02.01/c00003"
expect(response.code).to eq "301"
expect(response).to redirect_to("http://www.example.com/catalog/MC001-02-01_c00003")
end
我已经在几个地方阅读了重定向帮助器的文档。我看到我可以使用constraints
来正确地抓取整个id,尽管有点。因此,这适用于获取整个id:
get "/collections/:eadid/:componentid", to: redirect("/catalog/%{eadid}_%{componentid}"), constraints: { eadid: /([^/])+?/ }
返回/catalog/MC001.02.01_c00003
。接近,但不完全正确,因为我还需要用破折号替换点。
如果我需要做一些更复杂的逻辑,我也可以使用块格式,例如,字符串替换,像这样:
get "/collections/:eadid/:componentid", to: redirect { |params, request|
"/catalog/#{params[:eadid].gsub('.','-')}_#{params[:componentid]}"
}
这不起作用,因为在第一个点之后的eadid
位已被删除,正如我可以看到的,如果我检查params
和request
:
"action_dispatch.request.path_parameters"=>{:eadid=>"C0140", :componentid=>"c03411"}
我没能找到配置为使用constraint
和块的重定向helper的示例。对语法的猜测没有取得成果。有人知道这里的秘方吗?或者有更好的方法来解决我的问题?
谢谢!
来源参考:
- https://guides.rubyonrails.org/routing.html重定向
- https://api.rubyonrails.org/v6.1.0/classes/ActionDispatch/Routing/Redirection.html
- 可以在Rails中创建此重定向路由吗?
- https://avdi.codes/rails-3-resource-routes-with-dots-or-how-to-make-a-ruby-developer-go-a-little-bit-insane/
您必须注意块和散列之间相似(但不同)的语法
这是单行块的语法:
redirect {|params, request| ...}
这是Hash的语法:
{to: redirect("/catalog/%{eadid}_%{componentid}")}
当Hash是方法调用的最后一个参数时,{
和关闭}
是可选的,就像您的get
的情况一样。
现在,如果你想混合两者,你可能需要好好照顾你正在做的事情。
另一个解决方案是提取约束:
constraints(eadid: /[^/]+/) do
get "/collections/:eadid/:componentid", to: redirect { |params, request|
"/catalog/#{params[:eadid].gsub('.','-')}_#{params[:componentid]}"
}
end
我最终选择了这个,因为我发现它更容易阅读,但我可以确认Geoffroy的答案是有效的,我已经标记为可接受。
get "/collections/:eadid/:componentid", constraints: { eadid: /([^/])+?/ }, to: redirect { |params, _request|
"/catalog/#{params[:eadid].tr('.', '-')}_#{params[:componentid]}"
}
Geoffroy建议列出我已经猜到的语法,这也很有帮助。谢谢你!