4

On Rails的3斜線,我想從一個URL重定向沒有尾隨斜線有斜線的規範網址。重定向到規範的路線沒有尾隨的Rails 3

match "/test", :to => redirect("/test/") 

但是,上面的路由匹配/ test和/ test /導致重定向循環。

我如何度過,即使沒有斜槓唯一的版本一致?

回答

2

有一個在ActionDispatch一個選項叫做trailing_slash,您可以使用強制結尾的斜線的網址的結尾。我不確定它是否可以在路由定義中使用。

def tes_trailing_slsh 
    add_host! 
    options = {:controller => 'foo', :trailing_slash => true, :action => 'bar', :id => '33'} 
    assert_equal('http://www.basecamphq.com/foo/bar/33/', W.new.url_for(options)) 
end 

就你而言,最好的方法是使用Rack或Web服務器來執行重定向。 在Apache中,你可以不用斜線的定義添加如

RewriteEngine on 
RewriteRule ^(.+[^/])$ $1/ [R=301,L] 

重定向所有路由到相應的一個與斜線。

或者你可以使用rack-rewrite在Rails應用程序在機架級別執行相同的任務。

+0

rack-rewrite是一個有趣的選項。儘管如果可能的話,我更喜歡Rails中的一個解決方案,而無需使用額外的中間件,也不需要在Web服務器端進行。 – 2011-12-21 16:41:28

+1

實際上,當你調用'redirect(「/ test /」)'你正在使用一個Rack中間件。 ;) – 2011-12-21 17:45:19

0

也許它的工作原理與

match "/test$", :to => redirect("/test/") 
+1

不,不行 – 2011-12-21 14:23:07

2

我想做同樣有cannonical URL的博客,這個工程

match 'post/:year/:title', :to => redirect {|env, params| "/post/#{params[:year]}/#{params[:title]}/" }, :constraints => lambda {|r| !r.original_fullpath.end_with?('/')} 
    match 'post/:year/:title(/*file_path)' => 'posts#show', :as => :post, :format => false 

然後我還有一個規則,它與交易帖子內部的相對路徑。順序很重要,所以前者先排第一,後者排在第二位。

3

您可以強制在控制器級別的重定向。

# File: app/controllers/application_controller.rb 
class ApplicationController < ActionController::Base 

    protected 

    def force_trailing_slash 
    redirect_to request.original_url + '/' unless request.original_url.match(/\/$/) 
    end 
end 

# File: app/controllers/test_controller.rb 
class TestController < ApplicationController 

    before_filter :force_trailing_slash, only: 'test' # The magic 

    # GET /test/ 
    def test 
    # ... 
    end 
end 
+1

'original_url'還包括查詢參數,所以這個檢查捕獲太多。 – cburgmer 2016-02-10 15:22:25