我非常确定该错误与TenantIdLoader
模块的实际内容无关。相反,它与ActiveSupport
依赖关系有关。
我似乎无法克服这个错误。从我读过的内容来看,因为ActiveRecord::Base
正在重新加载或Company::TenantIdLoader
正在重新加载,并且它以某种方式无法通信。请帮忙!我真的希望能够升级到Rails 4.2。
我现在已经了解到这一点,因为我引用的Tenant
会自动重新加载。\ n \ n我需要能够实际引用该课程,所以有人知道如何解决这个问题吗?
配置/ application.rb中
config.autoload_paths += %W( #{config.root}/lib/company )
配置/初始化/ company.rb
ActionMailer::Base.send(:include, Company::TenantIdLoader)
LIB /公司/ 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
答案 0 :(得分:154)
Tenant
有点像红色鲱鱼 - 如果你引用了需要通过rails const_missing
技巧加载的任何应用程序,就会出现错误。
问题在于你正在重新加载某些东西(你的模块),然后把它包含在一些不可重新加载的东西中(ActiveRecord::Base
或者在前面的例子ActionMailer::Base
中)。在某些时候你的代码被重新加载,现在ActiveRecord仍然包含这个模块,即使rails认为它已经卸载了它。引用Tenant时会发生错误,因为这会导致rails运行其const_missing
挂钩以找出应该从中加载Tenant的位置,并且该代码会因为常量搜索所在的模块不在那里而烦恼。
有三种可能的解决方案:
停止将您的模块包含在不可重新加载的类中 - 根据需要包含到单个模型,控制器中或创建抽象基类并在其中包含模块。
通过将此模块存储在autoload_paths中的某个位置使该模块无法重新加载(您必须明确要求它,因为rails将不再为您神奇地加载它)
将租户更改为::租户(Object.const_missing
将被调用,而不是Tenant.const_missing
)
答案 1 :(得分:22)
将 ModuleName 更改为 :: ModuleName 为我工作。
答案 2 :(得分:3)
不确定这是否对任何人都有帮助,但是在发生似乎无关的更改之后,我突然开始发生这种情况。重新启动应用程序服务器后,它消失了。
答案 3 :(得分:0)
将ModuleName
更改为'ModuleName'.constantize
为我解决了这个问题。
答案 4 :(得分:0)
解决此问题的另一种方法是要求模块直接位于不可重新加载的文件中。
在lib/company/tenant_id_loader.rb
的顶部放置require_relative '../../app/models/tenant'
或任何与ID加载程序相对的租户模型路径。
答案 5 :(得分:-2)
对我有用的东西
将config.eager_load = false
更新为true
在config/environments/development.rb
Ruby 2.6.5
Rails 5.1.6
答案 6 :(得分:-6)
有时候你只是
重新启动服务器,
重新启动服务器,
重新启动服务器,!