【问题标题】:Rails: Request-based (& Database-based) RoutingRails:基于请求(和基于数据库)的路由
【发布时间】:2013-01-25 04:04:06
【问题描述】:

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

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

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,反之亦然。这就是为什么我必须按当前站点(按域)过滤 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('|')})"

但是 request 在 routes.rb 中不可用,我尝试的一切都不起作用。

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

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

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

【问题讨论】:

    标签: ruby-on-rails database routing request multi-tenant


    【解决方案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
    

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

    【讨论】:

    • 非常感谢,效果很好!我什至尝试使用高级约束,但想不出将传递的请求信息用于域查询和蛞蝓...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-26
    • 1970-01-01
    • 2017-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多