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,在每个控制器中按域自己定位用户,然后覆盖设计范围登录和按域注册。而且我不确定如何让Devise知道会话中的当前域名。顺便说一句,用户手动default_scope替换acts_as_tenant属于同样的奇怪错误。走这条路看起来很脏。
我正在寻找一个干净的解决方案好几天。我会非常感谢任何帮助。
答案 0 :(得分:3)
已修复,在application_controller
中,更改
before_filter :set_tenant
到
prepend_before_filter :set_tenant
为了在Devise检查用户会话之前默认_cope所有内容,包括User。