xxx 的副本已从模块树中删除,但仍处于活动状态 [英] A copy of xxx has been removed from the module tree but is still active

查看:24
本文介绍了xxx 的副本已从模块树中删除,但仍处于活动状态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm pretty sure the error has nothing to do with the actual content of the TenantIdLoader module. Instead, it has something to do with ActiveSupport Dependencies.

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

I can't seem to get past this error. From what I've read, it's because either ActiveRecord::Base is getting reloaded or Company::TenantIdLoader is 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.

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

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

config/application.rb

config/application.rb

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

config/initializers/company.rb

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

推荐答案

Tenant 有点像红鲱鱼 - 如果您引用任何需要由 rails 加载的应用程序,就会发生错误' const_missing 技巧.

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

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

The problem is that you are taking something reloadable (your module) and then including it in something not reloadable (ActiveRecord::Base or, 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_missing hooks 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.

有 3 种可能的解决方案:

There are 3 possible solutions:

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

  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.

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

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)

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

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

这篇关于xxx 的副本已从模块树中删除,但仍处于活动状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆