【问题标题】:Rails using routes.rb to redirect old URLsRails 使用 routes.rb 重定向旧 URL
【发布时间】:2011-05-31 07:04:52
【问题描述】:

我有一个在 Coldfusion 中构建的旧站点,一个在 Rails 中构建的新站点。我想将旧 URL 重定向到新 URL。我不确定路线是否可行(我是菜鸟)。 URL 将非常相似。这应该很容易,但我不确定最好的方法。

旧网址:

mysite.com/this-is-the-slug-right-here/

新网址:

mysite.com/blog/this-is-the-slug-right-here

这是问题所在,我有 3 种“内容类型”。旧网站 url 没有区分内容类型。新的 Rails 站点为每种内容类型都有一个控制器:博客、照片、移动照片。

所以在上面的示例中,/blog/ 是控制器(内容类型),this-is-the-slug-right-here 是内容的永久链接或 slug。我得到的是这样的:

@content = Content.where(:permalink => params[:id]).first

我应该使用 routes.rb,还是需要某种包罗万象的脚本?任何帮助我指出正确方向的帮助将不胜感激。


编辑以进一步澄清

这是一篇博文:http://jyoseph.com/treadmill-desk-walk-this-way/

此的新 URL 将是 /blog/treadmill-desk-walk-this-way,因为它是博客的内容类型。

还有一张照片贴:http://jyoseph.com/berries/

此的新 URL 将是 /photos/berries,因为它是照片的内容类型。

内容类型是内容模型上的一个属性,存储在属性content_type中。


这是我的 routes.rb 文件:

resources :contents
match 'mophoblog/:id', :to => 'mophoblog#show'
match 'photos/:id', :to => 'photos#show'
match 'blog/:id', :to => 'blog#show'

root :to => "index#index"   
match ':controller(/:action(/:id(.:format)))'

知道了,使用@mark 的回答,这就是我的结果。

在我的 routes.rb 中

match ':id' => 'contents#redirect',  :via => :get, :as => :id

在我的内容控制器中:

def redirect
  @content = Content.where(:permalink => params[:id]).first
  if @content.content_type.eql?('Photo')
    redirect_to "/photos/#{@content.permalink}", :status => :moved_permanently   
  elsif @content.content_type.eql?('Blog')
    redirect_to "/blog/#{@content.permalink}", :status => :moved_permanently   
  elsif @content.content_type.eql?('MoPhoBlog')   
    redirect_to "/mophoblog/#{@content.permalink}", :status => :moved_permanently   
  end
end 

我确信这可以改进,特别是我重定向的方式,但这完美地解决了我的问题。

【问题讨论】:

  • mysite.com/this-is-the-slug-right-here/ 这样的 URL 中,哪个部分允许您的重定向器将博客与 pix 等区别开来?
  • 当前 Coldfusion 站点的哪一部分?我将 isapi_rewrite 与 httpd.ini 文件一起使用。在新旧站点中,内容都存储在同一个表中,并按类型分隔。

标签: ruby-on-rails url routes


【解决方案1】:

您不能使用 routes.rb 来执行此操作,但是设置路由、获取内容类型和重定向非常简单。

类似:

routes.rb
match.resources :photos
match.resources :mobile_photos
match.resources :blog
#everything_else all resource and named routes before
match ':article_id' => 'articles#redirect',  :via => :get, :as => :article_redirect

#articles_controller.rb
def redirect
  @content = Content.find params[:id]
  if @content.content_type.eql?('photo')
    redirect_to photo_path(@content), :status => :moved_permanently
  elsif @content.content_type.eql?('mobile_photo')
    redirect_to mobile_photo_path(@content), :status => :moved_permanently
  ...
end

现在我在写这篇文章时突然想到,您可能只需要一个控制器来完成所有这些操作?

【讨论】:

  • 这实际上正是我所设想的工作方式。例如获取内容,找出内容类型并构建 URL(使用 /contenttype/permalink 或像您一样重定向)。当我实现示例代码时,我得到“No route matches /foo”,其中“foo”是您尝试访问的 URL。在进行任何更改之前,我将使用我的路由文件的内容更新问题。感谢您的帮助!
  • 请注意,我在重定向路线中有一个错字,我已更正,即。匹配 ':article_id' 匹配 'article_id'。
  • 投了反对票,因为它现在已经过时了。 stackoverflow.com/a/45190672/203673 现在是一个更好的答案。
【解决方案2】:

只是认为人们可能会对进行更通用重定向的解决方案感兴趣:

redirector = lambda do |env|
  path = env['action_dispatch.request.path_parameters'][:path]
  redirect("/new-url-base#{path}").call(env)
end

match 'old-url-base:path' => redirector, :constraints => {:path => /.*/}

redirect() 只返回一个返回重定向标头的简单机架应用程序,因此将其包装在 lambda 中允许您更改其参数。将其包装在一个对象中可能会更好:

match 'old-url-base:path' => Redirector.new("new-url-base", :path), :constraints => {:path => /.*/}

【讨论】:

    【解决方案3】:

    Rails 4 及更高版本支持内置重定向:

    http://guides.rubyonrails.org/routing.html#redirection

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-28
      • 1970-01-01
      • 2011-04-22
      • 2017-08-10
      • 1970-01-01
      • 2012-05-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多