没有子域名的多租户

时间:2013-05-17 19:10:00

标签: ruby-on-rails-3 routing multi-tenant

我观看了Ryan Bates Railscast#388关于多租户应用的默认范围。他是使用子域进行的。

由于一些原因,我希望能够在没有子域的情况下完成。例如:

tenantA.example.com - > example.com/tenantA

tenantB.example.com - > example.com/tenantB

不幸的是,唯一的方法是,我想出这样做是为了将我的所有资源嵌套在我的routes.rb文件中我的tenant资源中,这会产生副作用,要求我创建比首选嵌套路由更深的资源

我想知道是否有办法定义默认路由父级,以避免在每个路由助手中传递它。

1 个答案:

答案 0 :(得分:0)

我有一个类似的问题,他厌恶将我的范围包含在每一个路径助手调用中,因此我编写了以下助手:

module OverrideRoutesHelper
  %w(foo foo_bar).each do |resource|
    module_eval <<-EOT, __FILE__, __LINE__ + 1
      def #{resource}_path(*args) do_dat_thang!("#{resource}", *args) || super end
      def #{resource}_url(*args) do_dat_thang!("#{resource}", *args) || super end
    EOT
  end

  def do_dat_thang!(resource, obj, *args)
    if obj.is_a?(Integer)
      model = resource.split('_')[0].classify.constantize
      obj = model.find(obj)
    end
    send("tenant_#{resource}_path", obj.tenant, obj, *args)
  end
end

这是做什么的:

  1. 获取您在第一行(foofoo_bar
  2. 中提供的帮助资源
  3. 会覆盖_path_url帮助
  4. 调用do_dat_thang!,它会检查传入的对象是否会响应您的租户关联调用(如果这确实是您的关联名称)
  5. 如果是,则使用您最初传递的参数调用tenant_foo_pathtenant_foo_bar_path等,由在第一个对象参数上调用tenant检索到的租户预先添加。
  6. 所以,例如:

    foo_path(@foo)
    => tenant_foo_path(@foo.tenant, @foo)
    
    foo_bar_url(@foo, @bar)
    => tenant_foo_bar_url(@foo.tenant, @foo, @bar)
    

    另外,如果您提供ID而不是..

    foo_bar_path(1, 2)
    => tenant_foo_bar_path(Foo.find(1).tenant, Foo.find(1), 2)
    

    为我工作一个款待。虽然这有点神奇,但并不好。