Rails 3路线 - 允许slu ..

时间:2011-02-11 04:58:39

标签: ruby-on-rails ruby-on-rails-3 routes

设置路由以允许将额外的路径元素(一个slug)传递给Rails 3中的URL的正确方法是什么。我想不要打破一些你用show和new获得的魔法当您将对象列为资源时。

这是一个例子:
  http://somewebserver.com/topics/1/learning-rails
但我仍然希望这个工作   http://somewebserver.com/topics/1
这些
  http://somewebserver.com/topics/new
  http://somewebserver.com/topics/1/edit

2 个答案:

答案 0 :(得分:1)

虽然最好让你的slugs看起来像“1-learning-rails”,因为Rails 3现在allows the use of Rack applications来处理路由,所以你可以这样做:

# lib/topic_slugger.rb
class TopicSlugger
  AD_KEY = "action_dispatch.request.path_parameters"

  def self.call(env)
    controller = (env["PATH_INFO"].split("/")[1].camelize+"Controller").constantize
    glob = env[AD_KEY][:glob]
    slug, action_name = nil
    if glob
      path_params = glob.split("/")
      if path_params.length == 1
        if ["new","edit"].include?(path_params.first)
          # no slug present
          action_name = path_params.first
        else
          slug = path_params.first
        end
      else
        action_name = path_params.first
        slug = path_params.last
      end
    end
    env[AD_KEY][:slug] = slug if slug
    action = if action_name # "new" or "edit"
               action_name.to_sym
             else
               case env["REQUEST_METHOD"]
               when "PUT" then :update
               when "DELETE" then :destroy
               else :show
               end
             end
    controller.action(action).call(env)
  end
end

# config/routes.rb
require 'topic_slugger'

Ztest::Application.routes.draw do
  # handle show, new, edit, update, destroy
  match 'topics/:id/*glob' => TopicSlugger
  # handle index, create
  resources :topics
end

这会接受"/topics/1/foo/bar"形式的请求,并将它们传递给TopicSlugger Rack应用程序,该应用程序决定glob是否包含组合动作/ slug(如"new/learning-rails"),或只是一个slug({{ 1)}),将slug添加到环境的请求参数中,然后将环境传递给控制器​​操作,控制器操作本身就是一个Rack应用程序。 “index”和“create”通常由"learning-rails"语句处理。

因此,例如,resources将使用"GET /topics/1/new/learning-rails"

的参数哈希值发送到TopicsController#new

答案 1 :(得分:0)

由于/被视为路径分隔符,因此Rails建议您使用更“中立”的slug将ID与-分开。

请参阅this screencast

否则,您需要传递自定义:id验证,并让Rails知道:id可以包含/,但事情并非那么简单。