4

それぞれのオンライン VPS サーバーに複数のクライアント用に展開された中規模のアプリケーションがあります。コードはすべてのクライアントで同じです。メンテナンスは大きな負担になりつつあります。同じ変更でも、非常に多くのサーバーに展開しています。そのため、アプリケーションにマルチテナンシー機能を実装することを計画しています。

いくつかの宝石に出くわしましたが、それは目的を達成していないため、実装する予定です。

新しいモデルClientを作成し、abstract superclass継承するクラスを作成しActiveRecord::Base、すべての依存クラスがこのクラスを継承します。スーパークラスから追加default_scopeしたいときに問題が発生します。

class SuperClass < ActiveRecord::Base
  self.abstract_class = true
  default_scope where(:client_id => ???)
end 

??? ユーザーごとに変わります。したがって、静的な値を与えることはできません。しかし、このスコープを動的に設定する方法がわかりません。では、何ができるでしょうか?

4

1 に答える 1

5

次のようなことを行います (スレッドセーフな部分は必要ないかもしれません)。

class Client < ActiveRecord::Base
  def self.current
    Thread.current['current_client']
  end

  def self.current=(client)
    Thread.current['current_client'] = client
  end
end

class SuperClass < ActiveRecord::Base
  self.abstract_class = true
  # Note that the default scope has to be in a lambda or block. That means it's eval'd during each request.
  # Otherwise it would be eval'd at load time and wouldn't work as expected.
  default_scope { Client.current ? where(:client_id => Client.current.id ) : nil }
end

次に、ApplicationController で、サブドメインに基づいて現在のクライアントを設定する before フィルターを追加します。

class ApplicationController < ActionController::Base
  before_filter :set_current_client

  def set_current_client
    Client.current = Client.find_by_subdomain(request.subdomain)
  end
end
于 2012-10-13T22:36:17.757 に答える