5

宝石

ruby 1.9.3
rails 3.2.11
devise 2.2.3
acts_as_tenant 0.2.9

代码

我所有的模型都由 domain_id 限定:

class User < ActiveRecord::Base
  acts_as_tenant(:domain)
  #...
end

然后,在我的 application_controller 中,我从域中设置当前租户:

class ApplicationController < ActionController::Base
  set_current_tenant_through_filter
  before_filter :set_tenant
  protect_from_forgery
  #...

  def set_tenant
    #...
    @domain = Domain.find_or_create_by_name(request.host)
    set_current_tenant(@domain)
  end
end

除了会话之外,所有模型都适用于所有模型:每次加载页面时,它将注销第一个与另一个租户一起加载页面的用户。通过加载此页面,它将注销第一个 [... 等]

假设:当 Alice 访问一个域时,Rails 加载 current_tenant=alice_domain (ok)。一切都按预期工作,直到 Bob 访问另一个域,加载 current_tenant=bob_domain。当 Alice 刷新她的页面时,Rails 仍然有 current_tenant==bob_domain。Rails 检查会话:Alice 在 bob_domain 范围内不存在,因此 Devise 强制 Alice 注销。然后 application_controller 设置 current_tenant=alice_domain... 注销 Bob。

肮脏的解决方法:不要在用户模型中使用acts_as_tenant,在每个控制器中按域自己限定用户,然后覆盖设计以按域限定登录和注册。而且我不确定如何让设计了解会话内容中的当前域。顺便说一句,在用户中用手动 default_scope 替换acts_as_tenant 也会遇到同样奇怪的错误。走这条路似乎很脏。

我几天来一直在寻找一个干净的解决方案。如果有任何帮助,我将不胜感激。

4

1 回答 1

3

固定,在application_controller,改变

before_filter :set_tenant

prepend_before_filter :set_tenant

为了在设计检查用户会话之前对包括用户在内的所有内容进行 default_scope。

于 2013-02-03T16:25:48.300 回答