Ruby on rails xxx的副本已从模块树中删除,但仍处于活动状态
我很确定错误与Ruby on rails xxx的副本已从模块树中删除,但仍处于活动状态,ruby-on-rails,ruby,ruby-on-rails-4,Ruby On Rails,Ruby,Ruby On Rails 4,我很确定错误与TenantIdLoader模块的实际内容无关。相反,它与ActiveSupport依赖项有关 我似乎无法克服这个错误。从我所读到的,这是因为要么是ActiveRecord::Base被重新加载,要么是Company::tenatidloader被重新加载,而它不知何故没有传达这一点。救命啊!我非常希望能够升级到Rails 4.2 编辑 我现在了解到,这是因为我正在引用自动重新加载的Tenant。我需要能够实际引用这个类,所以有人知道如何绕过这个问题吗 config/applica
TenantIdLoader
模块的实际内容无关。相反,它与ActiveSupport
依赖项有关
我似乎无法克服这个错误。从我所读到的,这是因为要么是ActiveRecord::Base
被重新加载,要么是Company::tenatidloader
被重新加载,而它不知何故没有传达这一点。救命啊!我非常希望能够升级到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\u id\u 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
技巧需要加载的任何应用程序,就会出现错误
问题是,您正在获取一些可重新加载的内容(您的模块),然后将其包含在一些不可重新加载的内容中(ActiveRecord::Base
,或者在前面的示例中ActionMailer::Base
)。在某个时候,代码被重新加载,现在ActiveRecord仍然包含这个模块,即使rails认为它已经卸载了它。引用租户时会发生错误,因为这会导致rails运行其const_missing
钩子来找出租户应该从哪里加载,并且代码会崩溃,因为常量搜索开始的模块不应该在那里
有3种可能的解决方案:
Object.const\u missing
将被调用,而不是Tenant.const\u missing
)将模块名称更改为::模块名称对我来说很有效。不确定这是否对任何人都有帮助,但在一次看似无关的更改后,我突然发现这种情况。重新启动应用程序服务器后,它消失了。将
ModuleName
更改为'ModuleName'
将config.eager\u load=false更新为true
在config/environments/development.rb中
Ruby 2.6.5
Rails 5.1.6解决此问题的另一种方法是要求文件中直接包含不可重新加载的模块
在lib/company/tenant\u id\u loader.rb的顶部,放置require\u relative'../../app/models/tenant'
或任何与id loader相对的路径到租户模型。这个答案有帮助吗?您确定涉及租户类吗?如果你删除了使用Tenant的代码,你还会出错吗?@WaynnLue是的,我想这就是原因,我只是不知道如何修复它。@FrederickCheung我有另一个类似于此的文件,它以同样的方式出错,它总是在与Tenant相关的行上出错,所以这是我最好的猜测。虽然您在Rails中没有使用Wisper,但其他人可能会注意到,如果您不遵循本文中的建议,Wisper会一直导致此问题:我似乎找到了第三种解决方案,不过我想知道您是否知道它为什么有效。如果我引用的是::Tenant,那么一切都会神奇地发生。可能是因为它将它作为顶级常量加载?也许吧?那么将调用的是Object.const_missing,而不是YourModule.const_missing,所以应该使用:
返回到顶级,这对我也适用!我经常遇到这个问题,在我的例子中,它与spring有关,因此执行/bin/spring stop
可以解决它。我喜欢这是一个运行时Ruby/Rails错误-不同于任何其他语言,动态或非动态,Ruby为开发人员提供了真正无限的灵活性,在程序执行之前(以及以什么顺序执行),他们完全不知道在哪里定义了模块。设计得太好了。是的,绝对不要这样做。这将扼杀您在开发中重新加载代码的能力。