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)。ボブが別のドメインにアクセスするまで、すべてが期待どおりに機能し、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を上書きします。また、Devise にセッション内の現在のドメインを認識させる方法がわかりません。ちなみに、acts_as_tenant を user で手動の default_scope に置き換えると、同じ奇妙なバグに陥ります。この道を行くのはとても汚いようです。

私は何日もの間、きれいな解決策を探しています。どんな助けにもとても感謝しています。

4

1 に答える 1

3

修正済み、application_controller変更中

before_filter :set_tenant

prepend_before_filter :set_tenant

Deviseがユーザーのセッションをチェックする前に、ユーザーを含むすべてをdefault_scopeするために。

于 2013-02-03T16:25:48.300 に答える