【问题标题】:Rails 3 Routes - allowing for slugsRails 3 Routes - 允许蛞蝓
【发布时间】:2011-02-11 04:58:38
【问题描述】:

在 Rails 3 中设置路由以允许将额外的路径元素(slug)传递到 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

【问题讨论】:

  • URL stub 在 Rails 社区中通常被称为 URL slug。不要试图迂腐,只是想它可能有助于回答的人正确理解你的问题。

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


【解决方案1】:

虽然让你的 slug 看起来像“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("learning-rails"),补充说将 slug 传递给环境的请求参数,然后将环境传递给控制器​​动作,控制器动作本身就是一个 Rack 应用程序。 "index" 和 "create" 由resources 语句正常处理。

例如,"GET /topics/1/new/learning-rails" 将被分派到 TopicsController#new,参数哈希为 { :id => "1", :slug => "learning-rails, :glob => "new/learning-rails" }

【讨论】:

    【解决方案2】:

    因为/ 被视为路径分隔符,Rails 鼓励您使用更“中性”的- 将 ID 与 slug 分开。

    this screencast

    否则,您需要通过自定义的:id 验证并让Rails 知道:id 可以包含/,但这并不是那么简单。

    【讨论】:

      猜你喜欢
      • 2012-09-30
      • 1970-01-01
      • 1970-01-01
      • 2014-07-30
      • 2016-06-02
      • 2021-04-04
      • 2014-04-02
      • 2016-07-22
      • 2011-02-09
      相关资源
      最近更新 更多