Rails路由,约束和变量范围

时间:2014-07-18 08:53:57

标签: ruby-on-rails routes constraints

我有以下通配路线&约束设置......

get '*path' => 'profiles#show', constraints: SlugConstraint.new
get '*path' => 'blogs#show', constraints: SlugConstraint.new

class SlugConstraint
  def initialize
    @slugs = Slug.all.map(&:name)
  end

  def matches?(request)
    request.url =~ /\/(.+)/
    @slugs.include?($1)
  end
end

...基于我在此描述的问题的变体: Rails wildcard route with database lookup & multiple controllers

我现在的问题是,如果第一次调用 SlugConstraint.new 返回false(这样第二个routes.rb SlugConstraint.new 现在被调用)我不会我想要重做以下呼叫:

Slug.all.map(&:name)

如何从失败的第一个约束调用中正确保存(或范围)@slugs数据,以便在下一个约束调用中需要时可以访问它?

感谢。

1 个答案:

答案 0 :(得分:1)

<强>路由

您无法在同一路径中使用2种路由模式

当您向Rails(或任何其他MVC application)发送请求时,Rails将采用您发送的路径&amp;因此尝试为它分配正确的路线(controller#action)。

这顺序发生 - IE Rails会查看top -> bottom的路由,直到找到对应的路由。由于您有两条匹配相同path的路线,因此您将无法使用您拥有的设置

enter image description here

-

App-Wide Slugs

您正在寻找的是app-wide slugs - 这实际上意味着您可以管理单个slug路径,并在后端拥有一个系统来容纳它。< / p>

你正处于能够实现这一目标的边缘,虽然我没有任何代码可以提供帮助,I do have an idea, which I found here

#config/routes.rb
get '*path' => MyRouter.new, constraints: SlugConstraint.new

#lib/my_router.rb
class MyRouter
  def call(env)
    # Matched from routes, you can access all matched parameters
    view_name= env['action_dispatch.request.path_parameters'][:view_name]

    # Compute these the way you like, possibly using view_name
    controller= 'post' 
    my_action= 'show'

    controller_class= (controller + '_controller').camelize.constantize
    controller_class.action(my_action.to_sym).call(env)
  end
end

这将允许您拾取被阻塞的路径,同时路由到正确的控制器。这是完全未经测试的&amp;只是在黑暗中刺伤 - 如果你想和我一起过去,评论&amp;我们可以看看