1

我正在尝试摆脱我目前在我的应用程序中使用的一些范围前缀。

目前我的路线看起来像这样(简化示例):

scope 'p'
  get ':product_slug', as: :product
end
scope 't' do
  get ':text_slug', as: :text
end

例如生成这些路径:

/p/car
/t/hello-world

现在我希望路径在没有前缀字母 (p & t) 的情况下工作。所以我将蛞蝓限制在现有的数据库条目中(顺便说一句效果很好):

text_slugs = Text.all.map(&:slug)
get ':text_slug', as: :text, text_slug: Regexp.new( "(#{text_slugs.join('|')})"

product_slugs = Product.all.map(&:slug)
get ':product_slug', as: :product, product_slug: Regexp.new( "(#{product_slugs.join('|')})"

问题:

这是一个多租户应用程序,这意味着某人的 text_slug 可能是另一个人的 product_slug,反之亦然。这就是为什么我必须按当前站点(按域)过滤 slug。

解决方案如下所示:

text_slugs = Site.find_by_domain(request.host).texts.all.map(&:slug)
get ':text_slug', as: :text, text_slug: Regexp.new( "(#{text_slugs.join('|')})"

但是请求在 routes.rb 中不可用,我尝试的一切都行不通。

对 Rack::Request 的直接调用需要正确的 env 变量,该变量似乎不存在于 Application.routes 中,否则这可能会起作用:

req = Rack::Request.new(env)
req.host

我真的尝试了很多,并感谢任何提示!

4

1 回答 1

1

您可以为此使用高级约束:http: //guides.rubyonrails.org/routing.html#advanced-constraints

class SlugConstraint
  def initialize(type)
    @type = type
  end
  def matches?(request)
    # Find users subdomain and look for matching text_slugs - return true or false
  end
end

App::Application.routes.draw do
  match :product_slug => "products#index", :constraints => SlugConstraint.new(:product)
  match :tag_slug => "tags#index", :constraints => SlugConstraint.new(:tag)
end

顺便说一句 - 您可能会遇到测试问题,但这是另一个问题......

于 2013-01-24T20:04:06.383 回答