Uma cópia de xxx foi removida da árvore do módulo, mas ainda está ativa

129

Tenho certeza de que o erro não tem nada a ver com o conteúdo real do TenantIdLoadermódulo. Em vez disso, tem algo a ver com ActiveSupportdependências.

Não consigo superar esse erro. Pelo que li, é porque ActiveRecord::Baseestá sendo recarregado ou Company::TenantIdLoaderrecarregado, e de alguma forma não está comunicando isso. Ajuda por favor! Eu realmente gostaria de poder ser atualizado para o Rails 4.2.

EDITAR

Agora eu aprendi que é porque estou Tenantfazendo referência a qual está sendo recarregada automaticamente. Eu preciso ser capaz de realmente fazer referência à classe, então alguém sabe como contornar isso?

config / application.rb

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

config / inicializadores / empresa.rb

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

lib / company / 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
kddeisz
fonte
3
Esta resposta ajuda em tudo? stackoverflow.com/questions/17561697/…
Waynn Lue
Tem certeza de que a turma de inquilinos está envolvida? Se você apagar os bits desse código que usam o inquilino, ainda recebe um erro?
21715 Frederick Cheung
@WaynnLue sim, acho que é esse o motivo, simplesmente não sei como consertá-lo.
Kddeisz 17/04
@FrederickCheung Eu tenho outro arquivo semelhante a este que está com erros da mesma maneira, e sempre erros na linha relacionados ao inquilino, então é o meu melhor palpite.
Kddeisz 17/04
1
Embora você não esteja usando o Wisper no Rails aqui, pode ser útil para outras pessoas observar que o Wisper causa esse problema de maneira bastante consistente se você não seguir os conselhos deste segmento: stackoverflow.com/questions/28346609/…
Steve N

Respostas:

182

Tenanté uma espécie de arenque vermelho - o erro ocorreria se você referenciasse algum aplicativo que precise ser carregado pelo const_missingtruque dos trilhos .

O problema é que você está pegando algo recarregável (seu módulo) e, em seguida, incluindo-o em algo não recarregável ( ActiveRecord::Baseou, no seu exemplo anterior ActionMailer::Base). Em algum momento, seu código foi recarregado e agora o ActiveRecord ainda possui este módulo, mesmo que o Rails pense que o descarregou. O erro ocorre quando você faz referência ao inquilino porque isso faz com que os trilhos executem seus const_missingganchos para descobrir de onde o inquilino deve ser carregado e esse código fica assustador porque o módulo em que a pesquisa constante está começando não deve estar lá.

Existem 3 soluções possíveis:

  1. Pare de incluir seu módulo em classes não recarregáveis ​​- inclua em modelos individuais, controladores conforme necessário ou crie uma classe base abstrata e inclua o módulo.

  2. Torne este módulo não recarregável, armazenando-o em algum lugar que não esteja em autoload_paths (você precisará exigi-lo explicitamente, pois os trilhos não o carregarão mais magicamente para você)

  3. Alterar inquilino para :: inquilino ( Object.const_missingserá invocado, não Tenant.const_missing)

Frederick Cheung
fonte
30
Parece que encontrei uma terceira solução, embora estivesse pensando se você sabe por que isso funciona. Se eu referir que foi: Locatário, tudo funciona magicamente. Possivelmente porque está carregando como uma constante de nível superior? Talvez?
Kddeisz 19/04
3
então é Object.const_missing que será não sejam invocados YourModule.const_missing assim que as coisas devem funcionar
Frederick Cheung
6
Voltar para o nível superior usando ::funcionou para mim também!
Alex Moore-Niemi
7
Ocasionalmente, esse problema ocorria e, no meu caso, estava relacionado à primavera, portanto, ./bin/spring stopresolvê-lo.
11247 santuxus
2
Eu amo que este é um tempo de execução de erro Ruby / Rails - ao contrário de qualquer outra língua, dinâmico ou não, Ruby dá aos desenvolvedores a verdadeira flexibilidade ilimitada para ter literalmente nenhuma idéia de onde os módulos são definidos até que seus programa executa (e em que ordem ele executa). É tão bem desenhado.
Andy Ray
32

Alterar ModuleName para :: ModuleName funcionou para mim.

Aman Kumar
fonte
6

Não tenho certeza se isso vai ajudar alguém, mas de repente comecei a acontecer depois de uma mudança que parecia não ter relação. Ele desapareceu depois que eu reiniciei o servidor de aplicativos.

beef_boolean
fonte
0

Mudar ModuleNamepara 'ModuleName'.constantizeresolver o problema para mim.

Qortex
fonte
0

O que funcionou para mim:

Atualizar config.eager_load = falseparatrue

no config/environments/development.rb

Ruby 2.6.5
Rails 5.1.6

Jan Werkhoven
fonte
1
Sim, definitivamente não faça isso. Isso acabará com sua capacidade de recarregar o código no desenvolvimento.
kddeisz 03/03
-13

Às vezes você apenas

Reinicie seu servidor,

Albert.Qing
fonte
Não entendo por que reduzir a votação desta resposta? Repetir significa que é importante! Por que coisas simples têm muita bobagem?
precisa saber é o seguinte
7
Isso foi negado porque (a) não importa quantas vezes você reinicie o servidor, ele não resolverá o problema na pergunta original e (b) você não deve simplesmente tratar os sintomas de um problema, mas o problema em si.
tjbp
@tjbp plz cuidado com a palavra "às vezes" ok?
precisa saber é o seguinte
o problema é que é impossível depurar o aplicativo no modo de desenvolvimento se você precisar reiniciar o servidor após cada alteração.
Max Ivak
2
Vou votar nesta resposta porque se você estiver usando mongoid e excluir o objeto X do console do rails, você receberá este erro: A copy of X has been removed from the module tree but is still activeem todas as páginas que possuem Object Y.embeds Xe o servidor de reinicialização realmente funciona para este caso específico. Mas você deve editar sua resposta.
Lucas Andrade