Ruby-on-rails xxx 的副本已从模块树中删除,但仍处于活动状态

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29636334/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 00:11:54  来源:igfitidea点击:

A copy of xxx has been removed from the module tree but is still active

ruby-on-railsrubyruby-on-rails-4

提问by kddeisz

I'm pretty sure the error has nothing to do with the actual content of the TenantIdLoadermodule. Instead, it has something to do with ActiveSupportDependencies.

我很确定该错误与TenantIdLoader模块的实际内容无关。相反,它与ActiveSupport依赖关系有关。

I can't seem to get past this error. From what I've read, it's because either ActiveRecord::Baseis getting reloaded or Company::TenantIdLoaderis getting reloaded, and it's somehow not communicating that. Help, please! I'd really like to be able to get upgraded to Rails 4.2.

我似乎无法克服这个错误。从我读过的内容来看,这是因为要么ActiveRecord::Base正在重新Company::TenantIdLoader加载,要么正在重新加载,并且不知何故没有传达这一点。请帮忙!我真的很希望能够升级到 Rails 4.2。

EDIT

编辑

I've now learned that it's because I'm referencing Tenantwhich is getting reloaded automatically. I need to be able to actually reference the class though, so does anyone know how to get around this?

我现在知道这是因为我正在引用Tenant自动重新加载的内容。不过,我需要能够实际引用该类,所以有人知道如何解决这个问题吗?

config/application.rb

配置/应用程序.rb

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

config/initializers/company.rb

配置/初始化程序/company.rb

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

lib/company/tenant_id_loader.rb

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

回答by Frederick Cheung

Tenantis sort of a red herring - the error would occur if you referenced any bit of app that needs to be loaded by rails' const_missingtrick.

Tenant有点像红鲱鱼 - 如果您引用任何需要通过 railsconst_missing技巧加载的应用程序,就会发生错误。

The problem is that you are taking something reloadable (your module) and then including it in something not reloadable (ActiveRecord::Baseor, in your earlier example ActionMailer::Base). At some point your code is reloaded and now ActiveRecord still has this module included in it even though rails thinks it has unloaded it. The error occurs when you reference Tenant because that causes rails to run its const_missinghooks to find out where Tenant should be loaded from and that code freaks out because the module where the constant search is starting from shouldn't be there.

问题是您正在获取可重新加载的内容(您的模块),然后将其包含在不可重新加载的内容中(ActiveRecord::Base或者,在您之前的示例中ActionMailer::Base)。在某些时候你的代码被重新加载,现在 ActiveRecord 仍然包含这个模块,即使 rails 认为它​​已经卸载了它。当您引用 Tenant 时会发生错误,因为这会导致 rails 运行其const_missing钩子以找出应从何处加载租户,并且该代码会因为常量搜索开始的模块不应该在那里而出问题。

There are 3 possible solutions:

有3种可能的解决方案:

  1. Stop including your module into non reloadable classes - either include into individual models, controllers as needed or create an abstract base class and include the module in there.

  2. Make this module non reloadable by storing it somewhere that isn't in autoload_paths (you'll have to require it explicitly since rails will no longer load it magically for you)

  3. Changing Tenant to ::Tenant (Object.const_missingwill then be invoked, not Tenant.const_missing)

  1. 停止将您的模块包含到不可重新加载的类中 - 根据需要包含到单个模型、控制器中,或者创建一个抽象基类并将模块包含在其中。

  2. 通过将它存储在不在 autoload_paths 的某个地方来使这个模块不可重新加载(你必须明确地要求它,因为 rails 将不再为你神奇地加载它)

  3. 将 Tenant 更改为 ::Tenant (Object.const_missing然后将被调用,而不是Tenant.const_missing

回答by Aman Kumar

Changing ModuleNameto ::ModuleNameworked for me.

ModuleName更改为::ModuleName对我有用

回答by beef_boolean

Not sure if this will help anyone, but I had this suddenly start happening after a change that seemed unrelated. It went away after I restarted the application server.

不确定这是否会对任何人有所帮助,但是在似乎无关的更改之后,我突然开始发生这种情况。我重新启动应用程序服务器后它就消失了。

回答by Qortex

Changing ModuleNameto 'ModuleName'.constantizesolved the issue for me.

更改ModuleName'ModuleName'.constantize解决这个问题对我来说。

回答by Jan Werkhoven

What worked for me:

什么对我有用:

Update config.eager_load = falseto true

更新config.eager_load = falsetrue

in config/environments/development.rb

config/environments/development.rb

Ruby 2.6.5
Rails 5.1.6

红宝石 2.6.5
导轨 5.1.6

回答by Albert.Qing

Sometimes you just

有时你只是

Restart your server,

重启你的服务器,