Ich bin mir ziemlich sicher, dass der Fehler nichts mit dem tatsächlichen Inhalt des TenantIdLoader
Moduls zu tun hat . Stattdessen hat es etwas mit ActiveSupport
Abhängigkeiten zu tun .
Ich kann diesen Fehler scheinbar nicht überwinden. Nach dem, was ich gelesen habe, liegt es daran, dass entweder ActiveRecord::Base
neu geladen wird oder Company::TenantIdLoader
neu geladen wird, und dass dies irgendwie nicht kommuniziert wird. Hilfe bitte! Ich würde wirklich gerne ein Upgrade auf Rails 4.2 erhalten.
BEARBEITEN
Ich habe jetzt gelernt, dass es daran liegt, dass ich referenziere, Tenant
was automatisch neu geladen wird. Ich muss in der Lage sein, tatsächlich auf die Klasse zu verweisen. Weiß jemand, wie man das umgeht?
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
quelle
Antworten:
Tenant
ist eine Art roter Hering - der Fehler würde auftreten, wenn Sie auf eine App verweisen, die per Rails-const_missing
Trick geladen werden muss .Das Problem ist, dass Sie etwas nachladbares (Ihr Modul) nehmen und es dann in etwas nicht nachladbares (
ActiveRecord::Base
oder in Ihrem früheren BeispielActionMailer::Base
) aufnehmen. Irgendwann wird Ihr Code neu geladen und ActiveRecord enthält dieses Modul immer noch, obwohl Rails glaubt, es entladen zu haben. Der Fehler tritt auf, wenn Sie auf Tenant verweisen, da dies dazu führt, dass Rails ihreconst_missing
Hooks ausführen , um herauszufinden, von wo Tenant geladen werden soll, und dieser Code ausflippt, weil das Modul, von dem aus die konstante Suche beginnt, nicht vorhanden sein sollte.Es gibt 3 mögliche Lösungen:
Beenden Sie die Aufnahme Ihres Moduls in nicht nachladbare Klassen - fügen Sie sie entweder nach Bedarf in einzelne Modelle und Controller ein oder erstellen Sie eine abstrakte Basisklasse und fügen Sie das Modul dort ein.
Machen Sie dieses Modul nicht nachladbar, indem Sie es an einem Ort speichern, der nicht in autoload_paths enthalten ist (Sie müssen es explizit benötigen, da Rails es nicht mehr magisch für Sie laden).
Ändern des Mandanten in :: Mandant (
Object.const_missing
wird dann aufgerufen, nichtTenant.const_missing
)quelle
::
hat auch für mich funktioniert!./bin/spring stop
wurde es gelöst.Das Ändern von ModuleName in :: ModuleName hat bei mir funktioniert.
quelle
Ich bin mir nicht sicher, ob dies irgendjemandem helfen wird, aber ich hatte dies plötzlich nach einer Änderung, die nichts damit zu tun hatte. Es ging weg, nachdem ich den Anwendungsserver neu gestartet hatte.
quelle
Ändern,
ModuleName
um'ModuleName'.constantize
das Problem für mich zu lösen.quelle
Was hat bei mir funktioniert:
Update
config.eager_load = false
auftrue
im
config/environments/development.rb
Ruby 2.6.5
Rails 5.1.6
quelle
Manchmal bist du einfach
Starten Sie Ihren Server neu.
quelle
A copy of X has been removed from the module tree but is still active
Auf allen Seiten mit ObjectY.embeds X
und Neustart funktioniert der Server wirklich für diesen speziellen Fall. Aber Sie sollten Ihre Antwort bearbeiten.