注:原来的问题已经改变了一下。我找到了两种解决方案,并可能在完全改变设计的方式上。在任何情况下,我都会想知道,为什么RequestStore不工作(是因为Warden在中间件堆栈中拦截消息?),Thread.current如何工作,以及为什么实例变量是不稳定的解。设计和多租户范围
我已经在我的应用程序中使用default_scope启用了多租户,包括Devise User模型。
在application_controller.rb,我有
around_filter :set_request_store
def set_request_store
Tenant.current = current_tenant.id
yield
ensure
Tenant.current = nil
end
而且Tenant.current又设置了一个RequestStore哈希键。
在tenant.rb
def self.current
RequestStore.store[:current_tenant_id]
end
def self.current=(tenant_id)
RequestStore.store[:current_tenant_id] = tenant_id
end
在我的routes.rb文件,我有以下
unauthenticated do
root to: 'home#index', as: :public_root
end
authenticated :user do
root to: 'dashboard#index', as: :application_root
end
我面临的问题是更好地通过日志说明。
后
Started POST "https://stackoverflow.com/users/sign_in" for 127.0.0.1 at 2014-09-24 14:57:13 +0530
Processing by Devise::SessionsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"[FILTERED]", "user"=>{"tenant_id"=>"1", "email"=>"[email protected]", "password"=>"[FILTERED]"}}
Tenant Load (0.9ms) SELECT "tenants".* FROM "tenants" WHERE "tenants"."subdomain" = 'test' ORDER BY "tenants"."id" ASC LIMIT 1
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."tenant_id" = 1 AND "users"."email" = '[email protected]' ORDER BY "users"."id" ASC LIMIT 1
(0.2ms) BEGIN
SQL (0.5ms) UPDATE "users" SET "current_sign_in_at" = $1, "last_sign_in_at" = $2, "sign_in_count" = $3, "updated_at" = $4 WHERE "users"."id" = 1 [["current_sign_in_at", "2014-09-24 09:27:13.553818"], ["last_sign_in_at", "2014-09-24 09:26:31.548568"], ["sign_in_count", 44], ["updated_at", "2014-09-24 09:27:13.556155"]]
(1.1ms) COMMIT
在一个成功的标志。设计重定向应用(应用程序)的根路径。实际上,公共和应用程序根目录的路径是相同的。
Redirected to http://test.com.dev/
Completed 302 Found in 90ms (ActiveRecord: 3.4ms)
在路由未经身份验证的方法调用(可能)试图给用户(在中间件???使用看守的地方)认证和tenant_id没有设置在这一点上。请参阅tenant_id的WHERE子句。
Started GET "/" for 127.0.0.1 at 2014-09-24 14:57:13 +0530
User Load (0.8ms) SELECT "users".* FROM "users" WHERE "users"."tenant_id" IS NULL AND "users"."id" = 1 ORDER BY "users"."id" ASC LIMIT 1
Processing by HomeController#index as HTML
有没有人遇到过这样的问题并解决了它?
解决方案1:
首先,我一直在使用Thread.current解决它。出于某种原因,RequestStore.store没有在Devise方法中设置。
以下代码可解决登录问题。但是,我无法找到安全取消Thread.current值的地方。
在user.rb
devise ...,
request_keys: [:subdomain]
default_scope { where(tenant_id: (Tenant.current || Thread.current[:current_tenant_id])) }
protected
def self.find_for_authentication(warden_conditions)
subdomain = warden_conditions.delete(:subdomain)
Thread.current[:current_tenant_id] = Tenant.where(subdomain: subdomain).first.id
super
end
解决方案2:
UPDATE:这也有问题。这不总是工作。
改为使用实例变量。
在用户。RB
devise ...,
request_keys: [:subdomain]
default_scope { where(tenant_id: (Tenant.current || @tenant_id)) }
protected
def self.find_for_authentication(warden_conditions)
subdomain = warden_conditions.delete(:subdomain)
@tenant_id = Tenant.where(subdomain: subdomain).first.id
super
end
我想知道这将是一个更安全的方法,或是否有解决的更好的方法。
我原来的问题解决更优雅的使用这种方法。谢谢! – 2014-10-02 10:27:09
这个发现是一个绝对的创业板。有没有这个测试套件或宝石? – 2014-10-12 22:38:38