创建友好的Rails URL

时间:2011-02-21 21:57:21

标签: ruby-on-rails routing

我对一个相当常见的问题略有不同:SEO友好的URL。我有一个PagesController,所以我的网址当前就像(使用restful routing):

/页/一些内容标题

这很好用,但页面有层次结构,所以我需要以下内容:

/ some-content-title路由到/ pages / some-content-title

我也可以使用以下方式实现:

match '*a', :to => 'errors#routing'

在我的routes.rb中并​​将其捕获在ErrorsController中:

class ErrorsController < ApplicationController
  def routing
    Rails.logger.debug "routing error caught looking up #{params[:a]}"
    if p = Page.find_by_slug(params[:a])
      redirect_to(:controller => 'pages', :action => 'show', :id => p)
      return
    end
    render :file => "#{Rails.root}/public/404.html", :status => 404, :layout => false
  end
end

我的问题在于所需的SEO消除了URL的“pages /”部分。 SEO-dude想要什么(这里的例子是关键):

/ insurance =&gt; :controller =&gt;'pages',:id =&gt;'insurance'#但地址栏中的网址是/ insurance

/ insurance / car:controller =&gt;'pages',:category =&gt;'insurance',:id =&gt;'car'#,但地址栏中的网址是/ insurance / car

他是否有一种通用的方式让他获得他的谷歌爱情并让我保持路线健全?

谢谢!

2 个答案:

答案 0 :(得分:5)

这很难做到,因为您根据路径中的存在(或不存在)重新定义参数。您可以处理控制器中的globbed参数,但是您没有获得所需的URL,并且需要重定向。

Rails 3允许您在创建路径时将Rack应用程序用作端点。这个(可悲的未充分利用)功能有可能使路由非常灵活。例如:

class SeoDispatcher
  AD_KEY = "action_dispatch.request.path_parameters"

  def self.call(env)
    seopath = env[AD_KEY][:seopath]
    if seopath
      param1, param2 = seopath.split("/") # TODO handle paths with 3+ elements
      if param2.nil?
        env[AD_KEY][:id] = param1
      else
        env[AD_KEY][:category] = param1
        env[AD_KEY][:id] = param2
      end
    end
    PagesController.action(:show).call(env)
    # TODO error handling for invalid paths
  end
end
#

MyApp::Application.routes.draw do
  match '*seopath' => SeoDispatcher
end

将映射如下:

GET '/insurance'     => PagesController#show, :id => 'insurance'
GET '/insurance/car' => PagesController#show, :id => 'car', :category => 'insurance

并将保留您的SEO老兄要求的浏览器中的URL。

答案 1 :(得分:0)

这个名为friendly_id的宝石。见its github page