1

マルチテナントの「顧客」モデルは、「org _#{current_user.org.id} _customers」パターン(つまり、org_1_customers、org_2_customersなど)の複数の表のデータを表します。私はRequestStore gemを使ってcurrent_userのORG_IDを保存しています。マルチテナント・レールモデル継承

CURRENT組織のデータにアクセスするには、明示的に "Customer.org"(Customer.org.where(...)load)を呼び出す必要があります。これはたくさんのコードを書き直す必要があり、データにアクセスするたびに「org」を追加することを忘れないでください。

私の質問:「Customer」に電話して「Customer.org」にアクセスできるようにする方法があるので、現在のテナント/組織の顧客には「Customer」を使用し、「Customer.select_org (7)」他のテナント/組織の顧客については?

class ApplicationController < ActionController::Base 
    before_filter :find_organization 

    private 
    def find_organization 
     RequestStore[:current_org] = current_user ? current_user.org : nil 
    end 
end 

class SegregatedMultitenantModel < ActiveRecord::Base 
    self.abstract_class = true 

    def self.select_org(org_id) 
     @subdomain_classes ||= {} 
     unless @subdomain_classes[org_id] 
      @subdomain_classes[org_id] ||= Class.new(self) 
      @subdomain_classes[org_id].table_name = "org_#{org_id}_#{self.table_name}" # This needs sanitizing, of course 
      @subdomain_classes[org_id].reset_column_information 
     end 

     @subdomain_classes[org_id] 
    end 

    def self.org 
     if RequestStore[:current_org].nil? 
      raise "No Organization Selected For #{self.table_name}" 
     else 
      self.select_org(RequestStore[:current_org].id) 
     end 
    end 
end 

class Customer < SegregatedMultitenantModel 
end 

P.S.私のアプリケーションでは、テナント間のテーブルフィールドの違いにより、複数の顧客テーブルが必要です。

+0

'default_scope'を使用できませんか? – MrYoshiji

+0

私はテーブルを切り替えようとしており、default_scopeは1つのテーブル内のレコードをフィルタリングするためにのみ使用されています。 –

+0

私は「問題」それ自体はありません。私は、Customerモデルを使用するときに、テナント固有のテーブルを参照するというコンベンションで、自分のアプリケーションを構築しようとしています。したがって、リクエストごとに異なるでしょう。 –

答えて

0

私は解決策を考え出しました。それはどこにでもアプリで慣例により行をスコープと私はそれで満足している:

# Returns first row from "org_#{current_user.org.id}_customers" table 
MT::Customer.first 

# Returns first row from "org_3_customers" table 
MT::Customer.select_org(3).first 

これを行うには、まず、私はクラスに「スコープ」を分離:

class MT 

    @@segregated_organization_models = {} 

    def self.init(organizations, current_org, *options) 
     organizations.each do |org| 
      options[0][:segregated_models].each do |class_object| 
       # Create new model class 
       @@segregated_organization_models[org.id] ||= {} 

       a = Class.new(class_object) 
       @@segregated_organization_models[org.id][class_object.to_s.to_sym] = a 

       # Set correct table name 
       @@segregated_organization_models[org.id][class_object.to_s.to_sym].table_name = "org_#{org.id}_#{class_object.table_name}" 

       # Set default model class to current organization's model class 
       if org.id === current_org.id 
        self.const_set(class_object.to_s.to_sym, @@segregated_organization_models[org.id][class_object.to_s.to_sym]) 
       end 
      end 
     end 
    end 
end 

取得中RequestStore宝石とコントローラの賛成でモデルロジックのRID:

class ApplicationController < ActionController::Base 
    before_filter :find_organization 

    private 
    # Multitenancy helpers 

    def find_organization 
     MT.init(Organization.all, current_user.org, 
      segregated_models: [ 
       ArticleCategory, Article, CustomArticleField, 
       Customer, CustomerChange, CustomerLedgerItem 
      ] 
     ) 
    end 
end 

モデルの継承はまだそこにある:

匿名のコメント投稿者に感謝しています。有益な情報であなたの良い回答を削除しないでください!私はupvoteに何もない。笑。