Je suis pratiquement sûr que l'erreur n'a rien à voir avec le contenu réel du module TenantIdLoader
. Au lieu de cela, cela a quelque chose à voir avec ActiveSupport
Dépendances.
Je n'arrive pas à surmonter cette erreur. D'après ce que j'ai lu, c'est parce que ActiveRecord::Base
est en cours de rechargement ou Company::TenantIdLoader
est en cours de rechargement et que, d'une manière ou d'une autre, il ne communique pas cela. Aidez-moi, s'il vous plaît! J'aimerais vraiment pouvoir passer à la version Rails 4.2.
J'ai maintenant appris que c'est parce que je fais référence à Tenant
qui se recharge automatiquement. Je dois cependant pouvoir faire référence à la classe, alors est-ce que quelqu'un sait comment résoudre ce problème?
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
Tenant
est une sorte de redingote - l'erreur se produirait si vous faisiez référence à un élément d'application devant être chargé par le truc de Rails 'const_missing
.
Le problème est que vous prenez quelque chose de rechargeable (votre module) et que vous l'incluez ensuite dans quelque chose de non rechargeable (ActiveRecord::Base
ou, dans votre exemple précédent ActionMailer::Base
). À un moment donné, votre code est rechargé et maintenant, ActiveRecord a toujours ce module inclus même si Rails pense qu'il l'a déchargé. L'erreur se produit lorsque vous référencez Tenant parce que cela oblige Rails à exécuter ses crochets const_missing
pour savoir où Tenant doit être chargé et le code qui s'effondre, car le module à partir duquel la recherche de constante est lancée ne devrait pas être là.
Il y a 3 solutions possibles:
Arrêtez d'inclure votre module dans des classes non rechargeables - incluez dans des modèles individuels, des contrôleurs si nécessaire, ou créez une classe de base abstraite et intégrez-y le module.
Rendez ce module non rechargeable en le stockant quelque part qui ne se trouve pas dans autoload_paths (vous devrez le demander explicitement car Rails ne le chargera plus comme par magie).
Changer de locataire en :: Tenant (Object.const_missing
sera alors invoqué et non Tenant.const_missing
)
Changer Nom du module en :: Nom du module a fonctionné pour moi.
Je ne suis pas sûr que cela puisse aider quelqu'un, mais cela a soudainement commencé à se produire après un changement qui semblait ne pas être lié. Il est parti après avoir redémarré le serveur d'applications.