Una copia di xxx è stata rimossa dall'albero del modulo ma è ancora attiva


129

Sono abbastanza sicuro che l'errore non abbia nulla a che fare con il contenuto effettivo del TenantIdLoadermodulo. Invece, ha qualcosa a che fare con le ActiveSupportdipendenze.

Non riesco a superare questo errore. Da quello che ho letto, è perché o ActiveRecord::Baseviene ricaricato o Company::TenantIdLoaderviene ricaricato, e in qualche modo non lo comunica. Aiuto per favore! Mi piacerebbe davvero poter essere aggiornato a Rails 4.2.

MODIFICARE

Ora ho imparato che è perché sto facendo riferimento Tenantche viene 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

3
Questa risposta aiuta a tutti? stackoverflow.com/questions/17561697/...
Waynn Lue

Sei sicuro che sia coinvolta la classe degli inquilini? Se si eliminano i bit di quel codice che utilizzano il tenant, si ottiene ancora un errore?
Frederick Cheung,

@WaynnLue sì, penso che sia questo il motivo, non so come risolverlo.
kddeisz,

@FrederickCheung Ho un altro file simile a questo che sta sbagliando allo stesso modo, ed è sempre errori sulla linea relativa al Locatario, quindi la mia ipotesi migliore.
kddeisz,

1
Anche se non stai usando Wisper in Rails qui, può essere utile per altre persone notare che Wisper causa questo problema in modo abbastanza coerente se non segui i consigli in questo thread: stackoverflow.com/questions/28346609/…
Steve N

Risposte:


182

Tenantè una specie di aringa rossa - l'errore si verificherebbe se si fa riferimento a qualche bit di app che deve essere caricata dal const_missingtrucco delle rotaie .

Il problema è che stai prendendo qualcosa ricaricabile (il tuo modulo) e poi includendolo in qualcosa non ricaricabile ( ActiveRecord::Baseo, nel tuo 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 al Locatario perché ciò provoca l'esecuzione delle sue rotaieconst_missing hook per scoprire da dove deve essere caricato il Locatario e che il codice impazzisce perché il modulo da cui inizia la ricerca costante non dovrebbe essere lì.

Esistono 3 possibili soluzioni:

  1. Smetti di includere il tuo modulo in classi non ricaricabili - includi in singoli modelli, controller secondo necessità o crea una classe base astratta e includi il modulo in essa.

  2. Rendi questo modulo non ricaricabile memorizzandolo in un posto che non si trova in autoload_paths (dovrai richiederlo esplicitamente poiché le rotaie non lo caricheranno più magicamente per te)

  3. Modifica del titolare in :: titolare ( Object.const_missingverrà quindi invocato, non Tenant.const_missing)


30
Mi sembra di aver trovato una terza soluzione, anche se mi chiedevo se sai perché funziona. Se faccio riferimento era: Inquilino, tutto funziona magicamente. Forse perché lo sta caricando come costante di livello superiore? Può essere?
kddeisz,

3
quindi sarà Object.const_missing che verrà invocato non YourModule.const_missing, quindi le cose dovrebbero funzionare
Frederick Cheung,

6
Tornare ai massimi livelli anche usando ha ::funzionato per me!
Alex Moore-Niemi,

7
Ho avuto questo problema di tanto in tanto e nel mio caso era legato alla primavera, quindi farlo è ./bin/spring stopstato risolverlo.
santuxus,

2
ADORO che si tratti di un errore di runtime Ruby / Rails - a differenza di qualsiasi altra lingua, dinamica o no, Ruby offre agli sviluppatori la vera flessibilità illimitata per non avere letteralmente idea di dove siano definiti i moduli fino a quando il programma non viene eseguito (e in quale ordine viene eseguito). È così ben progettato.
Andy Ray,


6

Non sono sicuro che questo possa aiutare qualcuno, ma all'improvviso ho iniziato a succedere dopo un cambiamento che non sembrava correlato. È andato via dopo che ho riavviato il server delle applicazioni.


0

Cambiare ModuleNameper 'ModuleName'.constantizerisolvere il problema per me.


0

Cosa ha funzionato per me:

Aggiorna config.eager_load = falseatrue

nel config/environments/development.rb

Ruby 2.6.5
Rails 5.1.6


1
Sì, sicuramente non farlo. Questo ucciderà la tua capacità di ricaricare il codice in fase di sviluppo.
kddeisz,

-13

A volte solo tu

Riavvia il tuo server,


Non capisco perché sottovalutare questa risposta? Ripetere significa che è importante! Perché le cose semplici hanno molte sciocchezze?
Albert.Qing

7
Questo è sottovalutato perché (a) non importa quante volte riavvii il tuo server non risolverà il problema nella domanda originale, e (b) non dovresti semplicemente trattare i sintomi di un problema, ma il problema stesso.
tjbp,

@tjbp plz stai attento alla parola "a volte" ok?
Albert.Qing

il problema è che è impossibile eseguire il debug dell'applicazione in modalità di sviluppo se è necessario riavviare il server dopo ogni modifica.
Max Ivak,

2
Voterò questa risposta perché se stai usando mongoid ed elimini l'oggetto X dalla console di rails, otterrai questo errore: A copy of X has been removed from the module tree but is still activein tutte le pagine che hanno Object Y.embeds Xe il riavvio del server funziona davvero per questo caso specifico. Ma dovresti modificare la tua risposta.
Lucas Andrade,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.