2015-04-14 3 views
75

Sono abbastanza sicuro che l'errore non ha nulla a che fare con il contenuto effettivo del modulo TenantIdLoader. Invece ha qualcosa a che fare con le dipendenze di ActiveSupport.Una copia di xxx è stata rimossa dall'albero dei moduli ma è ancora attiva

Non riesco a superare questo errore. Da quello che ho letto, è perché ActiveRecord :: Base si sta ricaricando o Company :: TenantIdLoader si sta ricaricando, e in qualche modo non lo comunica. Aiuto per favore! Mi piacerebbe davvero essere in grado di passare a Rails 4.2.

EDIT

Ora ho imparato che è perché sto riferimento inquilino che sta ottenendo ricaricato automaticamente. Devo essere in grado di fare effettivamente riferimento alla classe, quindi qualcuno sa come aggirare questo?

config/application.rb

config.autoload_paths += %W(#{config.root}/lib/company) 

config/inizializzatori/company.rb

ActionMailer::Base.send(:include, Company::TenantIdLoader) 

lib/società/tenant_id_loader.rb

module Company 
    module TenantIdLoader 

    extend ActiveSupport::Concern 

    included do 
     cattr_accessor :tenant_dependency 
     self.tenant_dependency = {} 

     after_initialize do 
     self.tenant_id = Tenant.active.id if self.class.tenant_dependent? and self.new_record? and Tenant.active.present? and !Tenant.active.zero? 
     end 
    end 

    # class methods to be mixed in 
    module ClassMethods 

     # returns true if this model's table has a tenant_id 
     def tenant_dependent? 
     self.tenant_dependency[self.table_name] ||= self.column_names.include?('tenant_id') 
     end 

    end 

    end 
end 
+2

Questa risposta è utile? http://stackoverflow.com/questions/17561697/argumenterror-a-copy-of-applicationcontroller-has-been-removed-from-the-module/23008837#23008837 –

+0

Sei sicuro che la classe Tenant sia coinvolta? Se si eliminano i bit di quel codice che utilizzano Tenant, si ottiene comunque un errore? –

+0

@WaynnLue sì, penso che sia la ragione, non so come risolverlo. – kddeisz

risposta

105

Tenant è una sorta di rosso aringa - l'errore si verificherebbe se si facesse riferimento a qualsiasi bit di app che deve essere caricato dalle guide 'Trick.

Il problema è che si sta eseguendo qualcosa di ricaricabile (il modulo) e quindi includendolo in qualcosa che non è ricaricabile (ActiveRecord::Base o, nell'esempio precedente ActionMailer::Base). Ad un certo punto il tuo codice viene ricaricato e ora ActiveRecord ha ancora questo modulo incluso anche se rails pensa di averlo scaricato. L'errore si verifica quando si fa riferimento a Titano perché questo fa sì che le rotaie eseguano i suoi ganci per scoprire da dove deve essere caricato Tenant e quel codice si impegna perché il modulo da cui la ricerca costante inizia non dovrebbe essere lì.

Ci sono 3 possibili soluzioni:

  1. stop compreso il modulo in classi non ricaricabili - non includono in singoli modelli, i controller come necessario o creare una classe base astratta e includere il modulo in là.

  2. rendere questo non ricaricabile modulo memorizzando qualche parte che non è in autoload_paths (dovrete richiederlo esplicitamente dal rotaie non saranno più caricarlo magicamente per voi)

  3. Cambiare inquilino di :: tenant (Object.const_missing sarà poi invocato, non Tenant.const_missing)

+20

Mi sembra di aver trovato una terza soluzione, anche se mi chiedevo se sai perché funziona. Se mi riferisco a: Tenant, tutto funziona magicamente. Forse perché lo sta caricando come costante di primo livello? Può essere? – kddeisz

+3

quindi è Object.const_missing che verrà invocato non YourModule.const_missing, quindi le cose dovrebbero funzionare –

+0

Nice! Ti sto dando i punti perché mi hai portato alla risposta. Grazie! – kddeisz

7

Modifica NomeModulo a :: ModuleName ha lavorato per me.