如何从/:id重定向到/:friendly_id

时间:2014-02-16 23:35:53

标签: ruby-on-rails

当有人尝试使用旧/:id网址而不是首选/:friendly_id链接浏览页面时,是否可以强制执行301重定向?

Apparently such redirections help to tell Google that you have updated the link ..所以它停止显示旧的非友好链接。

5 个答案:

答案 0 :(得分:17)

使用最新版本的friendly_id(编写本答案时为5.0.3)和Rails 4,我在控制器中执行此操作:

class ItemsController < ApplicationController
  before_action :set_item, only: [:show, :edit, :update, :destroy]

  ...

  private

  def set_item
    @item = Item.friendly.find(params[:id])
    redirect_to action: action_name, id: @item.friendly_id, status: 301 unless @item.friendly_id == params[:id]
  end
end

以下是对redirect_to行的描述,逐段细分:

  • action: action_name会保留您要连接的操作(可以根据现有的before_action显示,编辑,更新或销毁),以便在您访问时/items/1/edit 1}}您将被重定向到/items/pretty-url/edit
  • id: @item.friendly_id可确保您重定向到的网址是漂亮的网址
  • status: 301将重定向设置为301,状态为SEO
  • unless @item.friendly_id == params[:id]确保我们不会重定向通过其漂亮网址访问@item的人

答案 1 :(得分:2)

刚刚定义了路径文件中的重定向

get '/:old_id', to: redirect {|params, req| "/#{X.find(params[:old_id]).friendly_id}" }

答案 2 :(得分:1)

<强>路线

我认为你的路线不是问题

问题是路由的后端处理(I.E是否使用friendly_id)。所有Google都会看到:

domain.com/users/45 
domain.com/users/your_user

如果这两条路线都有效,Google会很高兴。我认为您暗示如果您将路线更改为仅处理your_user,您需要能够让Google了解重定向


<强>重定向

考虑到你可以在后端处理idslug(如果你愿意,我们有代码),我会使用ActionDispatch::Routing::Redirection类来处理重定向:

  #config/routes.rb
  begin  
    User.all.each do |u|
        begin
          get "#{u.id}" => redirect("#{u.slug}")
        rescue
        end
      end
  rescue
  end

答案 3 :(得分:1)

虽然James Chevalier的答案是正确的,但您可以将此方法提取到ApplicationController,以便与使用FriendlyId的任何模型一起使用:

def redirect_resource_if_not_latest_friendly_id(resource)
  # This informs search engines with a 301 Moved Permanently status code that
  # the show should now be accessed at the new slug. Otherwise FriendlyId
  # would make the show accessible at all previous slugs.
  if resource.friendly_id != params[:id]
    redirect_to resource, status: 301
  end
end

正如您所看到的,也没有必要将特定的action密钥传递给redirect_to。将Rails模型传递给redirect_to将自动尝试访问关联的收集资源路由上的show操作(假设它以这种方式设置)。这也意味着没有必要传递id键,因为FriendlyId总是返回模型#to_param中的最新slug。

不是unless(令人困惑的语义)的忠实粉丝我倾向于回避它,但这更多是我个人的偏好。

答案 4 :(得分:0)

是的,您需要在config/routes.rb

上定义两条路线
get 'path/:id' => 'controller#action'
get 'path/:friendly_id' => 'controller#action_2'

然后在您的遗留action方法中,您需要提供

return redirect_to controller_action_2_path(friendly_id: friendly_id),
                   status: :moved_permanently

这将生成301响应代码。这将最终使机器人开始打你的新模式,而不会丢失任何流量或索引(SEO)。