我正在尝试摆脱我目前在我的应用中使用的一些范围前缀。
目前我的路线看起来像这样(简化示例):
scope 'p'
get ':product_slug', as: :product
end
scope 't' do
get ':text_slug', as: :text
end
例如生成这些路径:
/p/car
/t/hello-world
现在我希望路径在没有前缀字母(p& t)的情况下工作。所以我将slug限制为现有的数据库条目(顺便说一句,这很棒):
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,反之亦然。这就是为什么我必须通过当前站点(按域)过滤slu ..
解决方案如下所示:
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
我真的尝试了很多,感谢任何提示!
答案 0 :(得分: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
BTW - 您可能会遇到测试问题,但这是另一个问题......