1

Mein mandantenfähiges "Kunden" -Modell stellt Daten aus mehreren Tabellen in einem "org _ # {current_user.org.id} _customers" -Muster (d. H. Org_1_customers, org_2_customers usw.). Ich verwende RequestStore Gem, um die ORG_ID des aktuellen Benutzers zu speichern.Multitenant Rails-Modell Vererbung

Also das Problem ist, dass auf Daten der aktuellen Organisation zugreifen muss, muss ich explizit "Customer.org" (d. H. Customer.org.where (...). Load) aufrufen. Das erfordert, viel Code neu zu schreiben und daran zu erinnern, jedes Mal, wenn ich auf die Daten zugreife, "org" hinzuzufügen.

MEINE FRAGE IST: Gibt es eine Möglichkeit, es so zu machen, dass ich "Customer.org" aufrufen konnte, indem ich "Kunde" anrufe, also würde ich "Kunde" für die Kunden des aktuellen Mandanten/org und "Customer.select_org" verwenden (7) "Für die Kunden anderer Mieter/Org.

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. Meine Anwendung erfordert mehrere Kundentabellen aufgrund von Unterschieden in Tabellenfeldern zwischen Mandanten!

+0

Können Sie nicht ein 'default_scope' verwenden? obwohl es nur ein Symptom für ein größeres Problem erleichtern würde – MrYoshiji

+0

Ich versuche, zwischen Tabellen zu wechseln, und default_scope wird nur verwendet, um die Datensätze innerhalb einer Tabelle zu filtern. –

+0

Ich habe kein "Problem" per se. Ich versuche nur, meine App nach einer Konvention zu erstellen, die bei Verwendung des Kundenmodells auf eine mandantenspezifische Tabelle verweist. So wird es bei jeder Anfrage anders sein. –

Antwort

0

Ich habe eine Lösung gefunden! Es Tive die Zeilen durch Konvention überall in der App und ich bin zufrieden mit ihm:

# 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 

, dies zu tun, erstens, ich getrennt das „Scoping“ in einer Klasse:

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 

, während sich

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 

Modell Erbe ist immer noch da:

der Edelstein und Modell Logik für die Steuerung RequestStor befreien

Vielen Dank an einen anonymen Kommentator, der seine Antwort gelöscht hat. Bitte löschen Sie Ihre guten Antworten nicht mit nützlichen Informationen! Ich habe nichts zu verbessern. Lol.