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.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. 입주자 간의 테이블 필드가 다르기 때문에 신청서에 여러 고객 테이블이 필요합니다!

+0

'default_scope '을 사용할 수 없습니까? 더 큰 문제의 증상을 덜어 주겠다. – MrYoshiji

+0

나는 테이블 사이를 전환하려고하는데, default_scope은 한 테이블 내의 레코드를 필터링하는 데만 사용된다. –

+0

본인은 "문제"자체가 없습니다. 나는 고객 모델을 사용할 때 세입자 전용 테이블을 참조한다는 규칙에 따라 응용 프로그램을 작성하려고합니다. 따라서 각 요청마다 다를 것입니다. –

답변

0

솔루션을 찾았습니다. 가져 오는 동안

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 

: 그것은 어디에서나 응용 프로그램에 관례 행을 스코프 나는 그것으로 만족 해요 :

# 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 

먼저이 작업을 수행하기 위해, 나는 수업에 "범위 지정"을 분리 컨트롤러 대신 RequestStore 보석 및 모델 로직을 제거 :

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 할 것이 없다. Lol.