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