2014-02-16 37 views
8

如果有人嘗試使用舊的/:id網址瀏覽網頁,而不是首選的/:friendly_id鏈接,是否可以強制301重定向?如何將/:id重定向到/:friendly_id

Apparently such redirections help to tell Google that you have updated the link ..因此它停止顯示舊的非友好鏈接。

+0

請問這有幫助嗎? http://stackoverflow.com/questions/4814063/how-to-redirect-301-when-changed-routing-translation – rlecaro2

+0

瑣碎的答案是做你所期望的:查找友好的id並返回重定向。 –

+0

在你的控制器中,只需做一個redirect_to,將你的新路由作爲參數傳遞。 – Cristopher

回答

14

隨着最新版本的friendly_id(5.0。3在撰寫本回答)和導軌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你會被重定向到/items/pretty-url/edit
  • id: @item.friendly_id確保您的網址'正在r edirected的就是漂亮的URL
  • status: 301設置重定向到301的狀態,對於SEO
  • unless @item.friendly_id == params[:id]可以確保我們不會重定向誰通過其漂亮的URL訪問@item
+0

偉大的解決方案,謝謝! – zishe

+1

這個重定向將消滅任何參數與原始URL一起提交的ams。例如,'/ items/4?filter = new'會變成'/ items/item-slug-for-item-4',並刪除'filter'參數。要保存參數,請使用'redirect_to request.params.merge(id:@ event.friendly_id),狀態:301,除非@ item.friendly_id == params [:id]'。 – moveson

2

剛纔定義的路由裏面的重定向文件

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

這對我很好用! –

+0

替代方法:獲取「/ url_before」=>重定向(「/ url_after」) –

1

路線

我不認爲你的路線在這裏

問題的問題是路由的後端處理(IE是否使用friendly_id)。所有谷歌將看到的是:

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

如果這兩條路線的工作,谷歌會很高興。我想你暗指的想法,如果你改變了路線,只處理your_user,你需要能夠獲得谷歌欣賞重定向


重定向

考慮到你可以處理後端都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 
+0

感謝Rich。基本上我希望Google忘記舊的/:id風格的鏈接,因爲這些鏈接對他們的頁面排名系統來說似乎沒有多大價值。此外,結果中的網址突出顯示看起來並不甜。你認爲我正在以正確的方式進行嗎? – Abram

+0

語法錯誤,意外tSTRING_BEG,期待keyword_do或'{'或'('(SyntaxError) 獲得「#{s.id}」=>重定向「#{s.slug}」 – Abram

+0

應該是'u.id'and 'u.slug'抱歉 –

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)。

1

而詹姆斯騎士的

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 

正如你可以看到它也不必爲通:答案是正確的,你可以爲了與使用FriendlyId任何模型使用提取此方法將ApplicationController中action關鍵到redirect_to。將Rails模型傳遞到redirect_to將自動嘗試訪問相關集合資源路由上的show操作(假設它是以這種方式設置的)。這也意味着沒有必要通過id鍵,因爲FriendlyId總是返回模型的#to_param中的最新slu slu。

不是unless的巨大粉絲(令人困惑的語義)我傾向於迴避它,但這更多是我個人的偏好。