注:原來的問題已經改變了一下。我找到了兩種解決方案,並可能在完全改變設計的方式上。在任何情況下,我都會想知道,爲什麼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