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

Posted

技术标签:

【中文标题】xxx 的副本已从模块树中删除,但仍处于活动状态【英文标题】:A copy of xxx has been removed from the module tree but is still active 【发布时间】:2015-06-20 14:15:11 【问题描述】:

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

我似乎无法克服这个错误。根据我的阅读,这是因为 ActiveRecord::Base 正在重新加载或 Company::TenantIdLoader 正在重新加载,并且不知何故没有传达这一点。请帮忙!我真的很想升级到 Rails 4.2。

编辑

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

config/application.rb

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

config/initializers/company.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

【问题讨论】:

这个答案有帮助吗? ***.com/questions/17561697/… 您确定涉及到租户类吗?如果您将使用 Tenant 的代码部分剔除,您还会收到错误吗? @WaynnLue 是的,我认为这就是原因,我只是不知道如何解决它。 @FrederickCheung 我有另一个与此类似的文件,它以同样的方式出错,并且总是在与租户相关的行上出错,所以这是我最好的猜测。 虽然您在这里没有在 Rails 中使用 Wisper,但如果您不遵循此线程中的建议,其他人可能会注意到 Wisper 相当一致地导致此问题:***.com/questions/28346609/…跨度> 【参考方案1】:

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

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

有 3 种可能的解决方案:

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

    将此模块存储在 autoload_paths 之外的某个位置,使其不可重新加载(您必须明确要求它,因为 rails 将不再为您神奇地加载它)

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

【讨论】:

我似乎找到了第三种解决方案,但我想知道您是否知道它为什么有效。如果我引用它是 ::Tenant,那么一切都会神奇地进行。可能是因为它随后将其作为***常量加载?也许? 那么它将调用 Object.const_missing 而不是 YourModule.const_missing 所以事情应该会解决 使用:: 退出到顶层也对我有用! 我时不时会遇到这个问题,在我的情况下它与弹簧有关,所以 ./bin/spring stop 正在解决它。 我喜欢这是一个 runtime Ruby/Rails 错误 - 与任何其他语言(无论是否动态)不同,Ruby 为开发人员提供了真正无限的灵活性,让他们完全不知道模块在哪里被定义直到你的程序执行(以及它执行的order)。它设计得非常好。【参考方案2】:

ModuleName 更改为 ::ModuleName 对我有用。

【讨论】:

【参考方案3】:

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

【讨论】:

【参考方案4】:

ModuleName 更改为'ModuleName'.constantize 为我解决了这个问题。

【讨论】:

【参考方案5】:

解决此问题的另一种方法是在不可重新加载的文件中直接要求模块。

lib/company/tenant_id_loader.rb 的顶部放置require_relative '../../app/models/tenant' 或相对于租户模型的id 加载器的任何路径。

【讨论】:

【参考方案6】:

什么对我有用:

config.eager_load = false 更新为true

config/environments/development.rb

Ruby 2.6.5 导轨 5.1.6

【讨论】:

是的,绝对不要这样做。这会扼杀你在开发中重新加载代码的能力。

以上是关于xxx 的副本已从模块树中删除,但仍处于活动状态的主要内容,如果未能解决你的问题,请参考以下文章

如何重新添加 Bamboo 已自动删除的分支构建?

搜索栏处于活动状态时,状态栏图标变为黑色

如何保持一个图像按钮处于活动状态,直到单击另一个

FCM 点击如何在应用程序处于后台状态时打开用户指定的活动而不是默认活动

春季安全删除用户 - 会话仍处于活动状态

如果处于“处理应用程序传输”中的应用程序是不是已从 App Store 中删除