创建友好的Rails URL

Ste*_*oss 3 routing ruby-on-rails

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

/页/部分内容,标题

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

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

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

match '*a', :to => 'errors#routing'
Run Code Online (Sandbox Code Playgroud)

在我的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
Run Code Online (Sandbox Code Playgroud)

我的问题来自于URL的"页面/"部分所需的SEO消除.SEO-dude想要什么(这里是一个例子是关键):

/ insurance =>:controller =>'pages',:id =>'insurance'#,但地址栏中的url是/ insurance

/ insurance/car:controller =>'pages',:category =>'insurance',:id =>'car'#,但地址栏中的url是/ insurance/car

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

谢谢!

zet*_*tic 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
Run Code Online (Sandbox Code Playgroud)

将映射如下:

GET '/insurance'     => PagesController#show, :id => 'insurance'
GET '/insurance/car' => PagesController#show, :id => 'car', :category => 'insurance
Run Code Online (Sandbox Code Playgroud)

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