このエラーはモジュールの実際の内容とは何の関係もないことは確かですTenantIdLoader
。むしろ、依存関係と関係がありますActiveSupport
。
このエラーを解決できないようです。私が読んだところによると、ActiveRecord::Base
再ロード中かCompany::TenantIdLoader
再ロード中のいずれかが原因のようで、どういうわけかそれが伝達されていないようです。助けてください! Rails 4.2 にアップグレードできるようにしたいです。
編集
今では、自動的に再ロードされるものを参照しているためだとわかりましたTenant
。ただし、実際にクラスを参照できるようにする必要があるので、これを回避する方法を誰か知っていますか?
config/application.rb
config.autoload_paths += %W( #{config.root}/lib/company )
config/初期化子/company.rb
ActionMailer::Base.send(:include, Company::TenantIdLoader)
lib/company/テナントIDローダー.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
ベストアンサー1
Tenant
これは一種の誤解です。Rails のconst_missing
トリックで読み込む必要があるアプリの一部を参照すると、エラーが発生します。
問題は、再ロード可能なもの (モジュール) を取得して、それを再ロード不可能なもの (ActiveRecord::Base
または、以前の例ActionMailer::Base
) に含めていることです。ある時点でコードが再ロードされ、Rails はモジュールをアンロードしたと認識しているにもかかわらず、ActiveRecord にはまだこのモジュールが含まれています。Tenant を参照するとエラーが発生します。これにより、Rails はconst_missing
フックを実行して Tenant をどこからロードするかを調べますが、定数検索が開始されるモジュールはそこにあってはならないため、コードが異常終了します。
解決策は3つあります:
モジュールを再ロードできないクラスに含めるのをやめ、必要に応じて個々のモデルやコントローラーに含めるか、抽象基本クラスを作成してそこにモジュールを含めます。
このモジュールを autoload_paths 以外の場所に保存して、再読み込み不可にします (Rails が自動的にロードしなくなるため、明示的に要求する必要があります)
Tenant を ::Tenant (
Object.const_missing
が呼び出されますが、 は呼び出されませんTenant.const_missing
)に変更します。