【问题标题】:Multiple resource types at top level URLs顶级 URL 的多种资源类型
【发布时间】:2013-12-07 21:29:19
【问题描述】:

我有一个项目,其中客户坚持所有内容 URL 都是顶级的。这包括跨不同资源类型的 URL,例如:

/products      #=> The Category "products"
/privacy       #=> A content-managed SystemPage "privacy"
/foo-bar-baz   #=> An Article "foo bar baz" (user generated, no less)

显然,这是有问题的,至少引发了两个技术问题:

  1. 无法通过基于模式的方法处理路由
  2. 这些不同内容的 slug 在表中必须是唯一的。

更不用说它感觉与 Rails 本身是对立的,当然也不符合框架的预期模式。

话虽如此,我想知道是否有合理合理的方法来实现这一目标。

我的第一直觉是维护一个“slug”表,它将 slug 映射到资源类型并在站点根目录中通过 slug 执行查找,然后,如果可能的话,转发请求到适当的控制器。我即将研究这种可能性,但我想我应该看看其他人是否有解决这个问题的方法(除了解雇客户)。

【问题讨论】:

    标签: ruby-on-rails url ruby-on-rails-4


    【解决方案1】:

    在routes.rb中,可以

    match '/*', :controller => proc { (lookup the db here) }
    

    How to pass params to a block in Rails routes?

    另一种方法是尝试说服客户端接受带有前缀的 URL,例如 /category_products 或 /article_foo_bar,它们很容易设置 rails 方式

    【讨论】:

    • +1 谢谢,这让我思考并让我记住控制器操作只是机架端点。但是我不相信您可以将 proc 传递给 controller 选项,至少不能在 rails 4 中。
    • 是的,您可以拥有 :controller => proc { ...}.call,但不幸的是,它似乎只被评估一次并为后续请求缓存。但我想应该可以覆盖它。
    【解决方案2】:

    我将请求从一个控制器转发到另一个控制器的想法是错误的。在 Rails 3+ 中,您可以开箱即用地路由到 Rack 端点。这实际上是控制器操作本身的实现方式,作为机架端点。

    所以为了解决这个问题,我创建了一个简单的 Rack 应用程序,它为给定的 slug 查找 Permalink,它具有对不同资源类型之一的多态引用。然后控制器确定并将环境传递给动作。基本上是路由器内部的中间件层。

    基本上:

    class PermalinkRouter
      def call(env)
        req = ActionDispatch::Request.new(env)
    
        # will throw if not found
        permalink = Permalink.find_by!(slug: req.params['id'])
    
        # resource_controller is a method of permalink, which constantizes
        # a controller based on its resource_type.
        permalink.resource_controller.action(:show).call(env)
      end
    end
    
    get "/:id", to: PermalinkRouter.new
    

    每当创建一种资源类型时,就会生成永久链接本身,并处理构建独特的 slug。

    这超出了这个问题的范围,但是以这种方式将链接视为自己的资源允许我做一些其他有趣的事情,包括实现一个永久链接“历史”,旧链接在 301 重定向到当前资源 URL。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-20
      • 1970-01-01
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多